using System;
using System.Diagnostics;
using Community.CsharpSqlite.Entity;

namespace Community.CsharpSqlite
{
    public  class Pragma
    {
        /*
    ** 2003 April 6
    **
    ** The author disclaims copyright to this source code.  In place of
    ** a legal notice, here is a blessing:
    **
    **    May you do good and not evil.
    **    May you find forgiveness for yourself and forgive others.
    **    May you share freely, never taking more than you give.
    **
    *************************************************************************
    ** This file contains code used to implement the PRAGMA command.
    *************************************************************************
    **  Included in SQLite3 port to C#-SQLite;  2008 Noah B Hart
    **  C#-SQLite is an independent reimplementation of the SQLite software library
    **
    **  SQLITE_SOURCE_ID: 2010-03-09 19:31:43 4ae453ea7be69018d8c16eb8dabe05617397dc4d
    **
    **  $Header: Community.CsharpSqlite/src/pragma_c.cs,v 6604176a7dbe 2010/03/12 23:35:36 Noah $
    *************************************************************************
    */
        //#include "sqliteInt.h"

        /* Ignore this whole file if pragmas are disabled
    */
#if !SQLITE_OMIT_PRAGMA

        /*
** Interpret the given string as a safety level.  Return 0 for OFF,
** 1 for ON or NORMAL and 2 for FULL.  Return 1 for an empty or
** unrecognized string argument.
**
** Note that the values returned are one less that the values that
** should be passed into sqlite3BtreeSetSafetyLevel().  The is done
** to support legacy SQL code.  The safety level used to be boolean
** and older scripts may have used numbers 0 for OFF and 1 for ON.
*/

        private static byte getSafetyLevel(string z)
        {
            //                             /* 123456789 123456789 */
            string zText = "onoffalseyestruefull";
            var iOffset = new[] {0, 1, 2, 4, 9, 12, 16};
            var iLength = new[] {2, 2, 3, 5, 3, 4, 4};
            var iValue = new byte[] {1, 0, 0, 0, 1, 1, 2};
            int i, n;
            if (SqliteInt.Sqlite3Isdigit(z[0]))
            {
                return (byte) Custom.Atoi(z);
            }
            n = Utility.Sqlite3Strlen30(z);
            for (i = 0; i < Utility.ArraySize(iLength); i++)
            {
                if (iLength[i] == n && Utility.Sqlite3StrNICmp(zText.Substring(iOffset[i]), z, n) == 0)
                {
                    return iValue[i];
                }
            }
            return 1;
        }

        /*
    ** Interpret the given string as a boolean value.
    */

        private static byte getBoolean(string z)
        {
            return (byte) (getSafetyLevel(z) & 1);
        }

        /*
    ** Interpret the given string as a locking mode value.
    */

        private static int getLockingMode(string z)
        {
            if (z != null)
            {
                if (0 == Utility.Sqlite3StrICmp(z, "exclusive")) return PagerLockingMode.PAGER_LOCKINGMODE_EXCLUSIVE;
                if (0 == Utility.Sqlite3StrICmp(z, "normal")) return PagerLockingMode.PAGER_LOCKINGMODE_NORMAL;
            }
            return PagerLockingMode.PAGER_LOCKINGMODE_QUERY;
        }

#if !SQLITE_OMIT_AUTOVACUUM
        /*
** Interpret the given string as an auto-vacuum mode value.
**
** The following strings, "none", "full" and "incremental" are
** acceptable, as are their numeric equivalents: 0, 1 and 2 respectively.
*/

        private static byte getAutoVacuum(string z)
        {
            int i;
            if (0 == Utility.Sqlite3StrICmp(z, "none")) return AutoVacuumModel.BTREE_AUTOVACUUM_NONE;
            if (0 == Utility.Sqlite3StrICmp(z, "full")) return AutoVacuumModel.BTREE_AUTOVACUUM_FULL;
            if (0 == Utility.Sqlite3StrICmp(z, "incremental")) return AutoVacuumModel.BTREE_AUTOVACUUM_INCR;
            i = Custom.Atoi(z);
            return (byte) ((i >= 0 && i <= 2) ? i : 0);
        }
#endif
        // * if !SQLITE_OMIT_AUTOVACUUM */

#if !SQLITE_OMIT_PAGER_PRAGMAS
        /*
** Interpret the given string as a temp db location. Return 1 for file
** backed temporary databases, 2 for the Red-Black tree in memory database
** and 0 to use the compile-time default.
*/

        private static int getTempStore(string z)
        {
            if (z[0] >= '0' && z[0] <= '2')
            {
                return z[0] - '0';
            }
            else if (Utility.Sqlite3StrICmp(z, "file") == 0)
            {
                return 1;
            }
            else if (Utility.Sqlite3StrICmp(z, "memory") == 0)
            {
                return 2;
            }
            else
            {
                return 0;
            }
        }
#endif
        // * SQLITE_PAGER_PRAGMAS */

#if !SQLITE_OMIT_PAGER_PRAGMAS
        /*
** Invalidate temp storage, either when the temp storage is changed
** from default, or when 'file' and the temp_store_directory has changed
*/

        private static int invalidateTempStorage(Parse pParse)
        {
            sqlite3 db = pParse.db;
            if (db.aDb[1].pBt != null)
            {
                if (0 == db.autoCommit || sqlite3BtreeIsInReadTrans(db.aDb[1].pBt))
                {
                    Utility.Sqlite3ErrorMsg(pParse, "temporary storage cannot be changed " +
                                            "from within a transaction");
                    return StatusCode.SQLITE_ERROR;
                }
                sqlite3BtreeClose(ref db.aDb[1].pBt);
                db.aDb[1].pBt = null;
                Build.ResetInternalSchema(db, 0);
            }
            return StatusCode.SQLITE_OK;
        }
#endif
        // * SQLITE_PAGER_PRAGMAS */

#if !SQLITE_OMIT_PAGER_PRAGMAS
        /*
** If the TEMP database is open, close it and mark the database schema
** as needing reloading.  This must be done when using the SQLITE_TEMP_STORE
** or DEFAULT_TEMP_STORE pragmas.
*/

        private static int changeTempStorage(Parse pParse, string zStorageType)
        {
            int ts = getTempStore(zStorageType);
            sqlite3 db = pParse.db;
            if (db.temp_store == ts) return StatusCode.SQLITE_OK;
            if (invalidateTempStorage(pParse) != StatusCode.SQLITE_OK)
            {
                return StatusCode.SQLITE_ERROR;
            }
            db.temp_store = (byte) ts;
            return StatusCode.SQLITE_OK;
        }
#endif
        // * SQLITE_PAGER_PRAGMAS */

        /*
** Generate code to return a single integer value.
*/

        private static void returnSingleInt(Parse pParse, string zLabel, long value)
        {
            Vdbe v = SelectHelper.GetVdbe(pParse);
            int mem = ++pParse.nMem;
            //long* pI64 = sqlite3DbMallocRaw( pParse->db, sizeof( value ) );
            //if ( pI64 )
            //{
            //  memcpy( pI64, &value, sizeof( value ) );
            //}
            //VdbeAux.VdbeAddOp4( v, OPCode.OP_Int64, 0, mem, 0, (char*)pI64, P4Type.P4_INT64 );
            VdbeAux.VdbeAddOp4(v, OPCode.OP_Int64, 0, mem, 0, value, P4Type.P4_INT64);
            VdbeAux.VdbeSetNumCols(v, 1);
            VdbeAux.VdbeSetColName(v, 0, VdbeColnameType.COLNAME_NAME, zLabel, Const.SQLITE_STATIC);
            VdbeAux.VdbeAddOp2(v, OPCode.OP_ResultRow, mem, 1);
        }

#if !SQLITE_OMIT_FLAG_PRAGMAS
        /*
** Check to see if zRight and zLeft refer to a pragma that queries
** or changes one of the flags in db.flags.  Return 1 if so and 0 if not.
** Also, implement the pragma.
*/

        private struct sPragmaType
        {
            public readonly int mask; /* Mask for the db.flags value */
            public readonly string zName; /* Name of the pragma */

            public sPragmaType(string zName, int mask)
            {
                this.zName = zName;
                this.mask = mask;
            }
        }

        private static int flagPragma(Parse pParse, string zLeft, string zRight)
        {
            var aPragma = new[]
                              {
                                  new sPragmaType("full_column_names", Flag.SQLITE_FullColNames),
                                  new sPragmaType("short_column_names", Flag.SQLITE_ShortColNames),
                                  new sPragmaType("count_changes", Flag.SQLITE_CountRows),
                                  new sPragmaType("empty_result_callbacks", Flag.SQLITE_NullCallback),
                                  new sPragmaType("legacy_file_format", Flag.SQLITE_LegacyFileFmt),
                                  new sPragmaType("fullfsync", Flag.SQLITE_FullFSync),
                                  new sPragmaType("reverse_unordered_selects", Flag.SQLITE_ReverseOrder),
#if SQLITE_DEBUG
                                  new sPragmaType("sql_trace", Flag.SQLITE_SqlTrace),
                                  new sPragmaType("vdbe_listing", Flag.SQLITE_VdbeListing),
                                  new sPragmaType("vdbe_trace", Flag.SQLITE_VdbeTrace),
#endif
#if !SQLITE_OMIT_CHECK
                                  new sPragmaType("ignore_check_constraints", Flag.SQLITE_IgnoreChecks),
#endif
/* The following is VERY experimental */
                                  new sPragmaType("writable_schema", Flag.SQLITE_WriteSchema | Flag.SQLITE_RecoveryMode),
                                  new sPragmaType("omit_readlock", Flag.SQLITE_NoReadlock),
/* TODO: Maybe it shouldn't be possible to change the ReadUncommitted
** flag if there are any active statements. */
                                  new sPragmaType("read_uncommitted", Flag.SQLITE_ReadUncommitted),
                                  new sPragmaType("recursive_triggers", Flag.SQLITE_RecTriggers),
                                  /* This flag may only be set if both foreign-key and trigger support
    ** are present in the build.  */
#if !(SQLITE_OMIT_FOREIGN_KEY) && !(SQLITE_OMIT_TRIGGER)
                                  new sPragmaType("foreign_keys", Flag.SQLITE_ForeignKeys),
#endif
                              };
            int i;
            sPragmaType p;
            for (i = 0; i < Utility.ArraySize(aPragma); i++) //, p++)
            {
                p = aPragma[i];
                if (Utility.Sqlite3StrICmp(zLeft, p.zName) == 0)
                {
                    sqlite3 db = pParse.db;
                    Vdbe v;
                    v = SelectHelper.GetVdbe(pParse);
                    Debug.Assert(v != null); /* Already allocated by sqlite3Pragma() */
                    if (UnitTest.ALWAYS(v))
                    {
                        if (null == zRight)
                        {
                            returnSingleInt(pParse, p.zName, ((db.flags & p.mask) != 0) ? 1 : 0);
                        }
                        else
                        {
                            int mask = p.mask; /* Mask of bits to set or clear. */
                            if (db.autoCommit == 0)
                            {
                                /* Foreign key support may not be enabled or disabled while not
                ** in auto-commit mode.  */
                                mask &= ~(Flag.SQLITE_ForeignKeys);
                            }
                            if (getBoolean(zRight) != 0)
                            {
                                db.flags |= mask;
                            }
                            else
                            {
                                db.flags &= ~mask;
                            }

                            /* Many of the flag-pragmas modify the code generated by the SQL
              ** compiler (eg. count_changes). So add an opcode to expire all
              ** compiled SQL statements after modifying a pragma value.
              */
                            VdbeAux.VdbeAddOp2(v, OPCode.OP_Expire, 0, 0);
                        }
                    }

                    return 1;
                }
            }
            return 0;
        }
#endif
        // * SQLITE_OMIT_FLAG_PRAGMAS */

        /*
** Return a human-readable name for a constraint resolution action.
*/
#if !SQLITE_OMIT_FOREIGN_KEY
        private static string actionName(int action)
        {
            string zName;
            switch (action)
            {
                case OnConstraintError.OE_SetNull:
                    zName = "SET NULL";
                    break;
                case OnConstraintError.OE_SetDflt:
                    zName = "SET DEFAULT";
                    break;
                case OnConstraintError.OE_Cascade:
                    zName = "CASCADE";
                    break;
                case OnConstraintError.OE_Restrict:
                    zName = "RESTRICT";
                    break;
                default:
                    zName = "NO ACTION";
                    Debug.Assert(action == OnConstraintError.OE_None);
                    break;
            }
            return zName;
        }
#endif

        /*
    ** Process a pragma statement.
    **
    ** Pragmas are of this form:
    **
    **      PRAGMA [database.]id [= value]
    **
    ** The identifier might also be a string.  The value is a string, and
    ** identifier, or a number.  If minusFlag is true, then the value is
    ** a number that was preceded by a minus sign.
    **
    ** If the left side is "database.id" then pId1 is the database name
    ** and pId2 is the id.  If the left side is just "id" then pId1 is the
    ** id and pId2 is any empty string.
    */

        private class EncName
        {
            public readonly byte enc;
            public readonly string zName;

            public EncName(string zName, byte enc)
            {
                this.zName = zName;
                this.enc = enc;
            }
        };

        // OVERLOADS, so I don't need to rewrite parse.c
        private static void sqlite3Pragma(Parse pParse, Token pId1, Token pId2, int null_4, int minusFlag)
        {
            sqlite3Pragma(pParse, pId1, pId2, null, minusFlag);
        }

        private static void sqlite3Pragma(
            Parse pParse,
            Token pId1, /* First part of [database.]id field */
            Token pId2, /* Second part of [database.]id field, or NULL */
            Token pValue, /* Token for <value>, or NULL */
            int minusFlag /* True if a '-' sign preceded <value> */
            )
        {
            string zLeft = null; /* Nul-terminated UTF-8 string <id> */
            string zRight = null; /* Nul-terminated UTF-8 string <value>, or NULL */
            string zDb = null; /* The database name */
            var pId = new Token(); /* Pointer to <id> token */
            int iDb; /* Database index for <database> */
            sqlite3 db = pParse.db;
            Db pDb;
            Vdbe v = pParse.pVdbe = VdbeAux.VdbeCreate(db);
            if (v == null) return;
            VdbeAux.VdbeRunOnlyOnce(v);
            pParse.nMem = 2;

            /* Interpret the [database.] part of the pragma statement. iDb is the
      ** index of the database this pragma is being applied to in db.aDb[]. */
            iDb = Build.TwoPartName(pParse, pId1, pId2, ref pId);
            if (iDb < 0) return;
            pDb = db.aDb[iDb];

            /* If the temp database has been explicitly named as part of the
      ** pragma, make sure it is open.
      */
            if (iDb == 1 && Build.OpenTempDatabase(pParse) != 0)
            {
                return;
            }

            zLeft = Build.NameFromToken(db, pId);
            if (zLeft == "") return;
            if (minusFlag != 0)
            {
                zRight = (pValue == null) ? "" : Print.MPrintf(db, "-%T", pValue);
            }
            else
            {
                zRight = Build.NameFromToken(db, pValue);
            }

            Debug.Assert(pId2 != null);
            zDb = pId2.n > 0 ? pDb.zName : null;
#if !SQLITE_OMIT_AUTHORIZATION
if ( sqlite3AuthCheck( pParse, ActionCode.SQLITE_PRAGMA, zLeft, zRight, zDb ) )
{
goto pragma_out;
}
#endif
#if !SQLITE_OMIT_PAGER_PRAGMAS
            /*
**  PRAGMA [database.]default_cache_size
**  PRAGMA [database.]default_cache_size=N
**
** The first form reports the current persistent setting for the
** page cache size.  The value returned is the maximum number of
** pages in the page cache.  The second form sets both the current
** page cache size value and the persistent page cache size value
** stored in the database file.
**
** The default cache size is stored in meta-value 2 of page 1 of the
** database file.  The cache size is actually the absolute value of
** this memory location.  The sign of meta-value 2 determines the
** synchronous setting.  A negative value means synchronous is off
** and a positive value means synchronous is on.
*/
            if (Utility.Sqlite3StrICmp(zLeft, "default_cache_size") == 0)
            {
                var getCacheSize = new[]
                                       {
                                           new VdbeOpList(OPCode.OP_Transaction, 0, 0, 0), /* 0 */
                                           new VdbeOpList(OPCode.OP_ReadCookie, 0, 1, BtreeMeta.BTREE_DEFAULT_CACHE_SIZE), /* 1 */
                                           new VdbeOpList(OPCode.OP_IfPos, 1, 7, 0),
                                           new VdbeOpList(OPCode.OP_Integer, 0, 2, 0),
                                           new VdbeOpList(OPCode.OP_Subtract, 1, 2, 1),
                                           new VdbeOpList(OPCode.OP_IfPos, 1, 7, 0),
                                           new VdbeOpList(OPCode.OP_Integer, 0, 1, 0), /* 6 */
                                           new VdbeOpList(OPCode.OP_ResultRow, 1, 1, 0),
                                       };
                int addr;
                if (Prepare.ReadSchema(pParse) != 0) goto pragma_out;
                VdbeAux.VdbeUsesBtree(v, iDb);
                if (null == zRight)
                {
                    VdbeAux.VdbeSetNumCols(v, 1);
                    VdbeAux.VdbeSetColName(v, 0, VdbeColnameType.COLNAME_NAME, "cache_size", Const.SQLITE_STATIC);
                    pParse.nMem += 2;
                    addr = VdbeAux.VdbeAddOpList(v, getCacheSize.Length, getCacheSize);
                    VdbeAux.VdbeChangeP1(v, addr, iDb);
                    VdbeAux.VdbeChangeP1(v, addr + 1, iDb);
                    VdbeAux.VdbeChangeP1(v, addr + 6, Const.SQLITE_DEFAULT_CACHE_SIZE);
                }
                else
                {
                    int size = Custom.Atoi(zRight);
                    if (size < 0) size = -size;
                    Build.BeginWriteOperation(pParse, 0, iDb);
                    VdbeAux.VdbeAddOp2(v, OPCode.OP_Integer, size, 1);
                    VdbeAux.VdbeAddOp3(v, OPCode.OP_ReadCookie, iDb, 2, BtreeMeta.BTREE_DEFAULT_CACHE_SIZE);
                    addr = VdbeAux.VdbeAddOp2(v, OPCode.OP_IfPos, 2, 0);
                    VdbeAux.VdbeAddOp2(v, OPCode.OP_Integer, -size, 1);
                    VdbeAux.VdbeJumpHere(v, addr);
                    VdbeAux.VdbeAddOp3(v, OPCode.OP_SetCookie, iDb, BtreeMeta.BTREE_DEFAULT_CACHE_SIZE, 1);
                    pDb.pSchema.cache_size = size;
                    sqlite3BtreeSetCacheSize(pDb.pBt, pDb.pSchema.cache_size);
                }
            }
            else

                /*
        **  PRAGMA [database.]page_size
        **  PRAGMA [database.]page_size=N
        **
        ** The first form reports the current setting for the
        ** database page size in bytes.  The second form sets the
        ** database page size value.  The value can only be set if
        ** the database has not yet been created.
        */ if (Utility.Sqlite3StrICmp(zLeft, "page_size") == 0)
                {
                    Btree pBt = pDb.pBt;
                    Debug.Assert(pBt != null);
                    if (null == zRight)
                    {
                        int size = UnitTest.ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0;
                        returnSingleInt(pParse, "page_size", size);
                    }
                    else
                    {
                        /* Malloc may fail when setting the page-size, as there is an internal
            ** buffer that the pager module resizes using Malloc.sqlite3_realloc().
            */
                        db.nextPagesize = Custom.Atoi(zRight);
                        if (StatusCode.SQLITE_NOMEM == sqlite3BtreeSetPageSize(pBt, db.nextPagesize, -1, 0))
                        {
                            ////        db.mallocFailed = 1;
                        }
                    }
                }
                else

                    /*
          **  PRAGMA [database.]max_page_count
          **  PRAGMA [database.]max_page_count=N
          **
          ** The first form reports the current setting for the
          ** maximum number of pages in the database file.  The
          ** second form attempts to change this setting.  Both
          ** forms return the current setting.
          */ if (Utility.Sqlite3StrICmp(zLeft, "max_page_count") == 0)
                    {
                        Btree pBt = pDb.pBt;
                        int newMax = 0;
                        Debug.Assert(pBt != null);
                        if (zRight != null)
                        {
                            newMax = Custom.Atoi(zRight);
                        }
                        if (UnitTest.ALWAYS(pBt))
                        {
                            newMax = sqlite3BtreeMaxPageCount(pBt, newMax);
                        }
                        returnSingleInt(pParse, "max_page_count", newMax);
                    }
                    else

                        /*
            **  PRAGMA [database.]secure_delete
            **  PRAGMA [database.]secure_delete=ON/OFF
            **
            ** The first form reports the current setting for the
            ** secure_delete flag.  The second form changes the secure_delete
            ** flag setting and reports thenew value.
            */ if (Utility.Sqlite3StrICmp(zLeft, "secure_delete") == 0)
                        {
                            Btree pBt = pDb.pBt;
                            int b = -1;
                            Debug.Assert(pBt != null);
                            if (zRight != null)
                            {
                                b = getBoolean(zRight);
                            }
                            if (pId2.n == 0 && b >= 0)
                            {
                                int ii;
                                for (ii = 0; ii < db.nDb; ii++)
                                {
                                    sqlite3BtreeSecureDelete(db.aDb[ii].pBt, b);
                                }
                            }
                            b = sqlite3BtreeSecureDelete(pBt, b);
                            returnSingleInt(pParse, "secure_delete", b);
                        }

                        else
                            /*
              **  PRAGMA [database.]page_count
              **
              ** Return the number of pages in the specified database.
              */ if (Utility.Sqlite3StrICmp(zLeft, "page_count") == 0)
                            {
                                int iReg;
                                if (Prepare.ReadSchema(pParse) != 0) goto pragma_out;
                                Build.CodeVerifySchema(pParse, iDb);
                                iReg = ++pParse.nMem;
                                VdbeAux.VdbeAddOp2(v, OPCode.OP_Pagecount, iDb, iReg);
                                VdbeAux.VdbeAddOp2(v, OPCode.OP_ResultRow, iReg, 1);
                                VdbeAux.VdbeSetNumCols(v, 1);
                                VdbeAux.VdbeSetColName(v, 0, VdbeColnameType.COLNAME_NAME, "page_count", Const.SQLITE_STATIC);
                            }
                            else

                                /*
              **  PRAGMA [database.]page_count
              **
              ** Return the number of pages in the specified database.
              */ if (zLeft == "page_count")
                                {
                                    Vdbe _v;
                                    int iReg;
                                    _v = SelectHelper.GetVdbe(pParse);
                                    if (_v == null || Prepare.ReadSchema(pParse) != 0) goto pragma_out;
                                    Build.CodeVerifySchema(pParse, iDb);
                                    iReg = ++pParse.nMem;
                                    VdbeAux.VdbeAddOp2(_v, OPCode.OP_Pagecount, iDb, iReg);
                                    VdbeAux.VdbeAddOp2(_v, OPCode.OP_ResultRow, iReg, 1);
                                    VdbeAux.VdbeSetNumCols(_v, 1);
                                    VdbeAux.VdbeSetColName(_v, 0, VdbeColnameType.COLNAME_NAME, "page_count", Const.SQLITE_STATIC);
                                }
                                else

                                    /*
                **  PRAGMA [database.]locking_mode
                **  PRAGMA [database.]locking_mode = (normal|exclusive)
                */ if (Utility.Sqlite3StrICmp(zLeft, "locking_mode") == 0)
                                    {
                                        string zRet = "normal";
                                        int eMode = getLockingMode(zRight);

                                        if (pId2.n == 0 && eMode == PagerLockingMode.PAGER_LOCKINGMODE_QUERY)
                                        {
                                            /* Simple "PRAGMA locking_mode;" statement. This is a query for
                    ** the current default locking mode (which may be different to
                    ** the locking-mode of the main database).
                    */
                                            eMode = db.dfltLockMode;
                                        }
                                        else
                                        {
                                            Pager pPager;
                                            if (pId2.n == 0)
                                            {
                                                /* This indicates that no database name was specified as part
                      ** of the PRAGMA command. In this case the locking-mode must be
                      ** set on all attached databases, as well as the main db file.
                      **
                      ** Also, the sqlite3.dfltLockMode variable is set so that
                      ** any subsequently attached databases also use the specified
                      ** locking mode.
                      */
                                                int ii;
                                                Debug.Assert(pDb == db.aDb[0]);
                                                for (ii = 2; ii < db.nDb; ii++)
                                                {
                                                    pPager = sqlite3BtreePager(db.aDb[ii].pBt);
                                                    sqlite3PagerLockingMode(pPager, eMode);
                                                }
                                                db.dfltLockMode = (byte) eMode;
                                            }
                                            pPager = sqlite3BtreePager(pDb.pBt);
                                            eMode = sqlite3PagerLockingMode(pPager, eMode) ? 1 : 0;
                                        }

                                        Debug.Assert(eMode == PagerLockingMode.PAGER_LOCKINGMODE_NORMAL ||
                                                     eMode == PagerLockingMode.PAGER_LOCKINGMODE_EXCLUSIVE);
                                        if (eMode == PagerLockingMode.PAGER_LOCKINGMODE_EXCLUSIVE)
                                        {
                                            zRet = "exclusive";
                                        }
                                        VdbeAux.VdbeSetNumCols(v, 1);
                                        VdbeAux.VdbeSetColName(v, 0, VdbeColnameType.COLNAME_NAME, "locking_mode", Const.SQLITE_STATIC);
                                        VdbeAux.VdbeAddOp4(v, OPCode.OP_String8, 0, 1, 0, zRet, 0);
                                        VdbeAux.VdbeAddOp2(v, OPCode.OP_ResultRow, 1, 1);
                                    }
                                    else
                                        /*
                  **  PRAGMA [database.]journal_mode
                  **  PRAGMA [database.]journal_mode = (delete|persist|off|truncate|memory)
                  */ if (zLeft == "journal_mode")
                                        {
                                            int eMode;
                                            var azModeName = new[]
                                                                 {
                                                                     "delete", "persist", "off", "truncate", "memory"
                                                                 };

                                            if (null == zRight)
                                            {
                                                eMode = PagerJournalMode.PAGER_JOURNALMODE_QUERY;
                                            }
                                            else
                                            {
                                                int n = Utility.Sqlite3Strlen30(zRight);
                                                eMode = azModeName.Length - 1;
                                                    //sizeof(azModeName)/sizeof(azModeName[0]) - 1;
                                                while (eMode >= 0 &&
                                                       String.Compare(zRight, azModeName[eMode],
                                                                      StringComparison.InvariantCultureIgnoreCase) != 0)
                                                {
                                                    eMode--;
                                                }
                                            }
                                            if (pId2.n == 0 && eMode == PagerJournalMode.PAGER_JOURNALMODE_QUERY)
                                            {
                                                /* Simple "PRAGMA journal_mode;" statement. This is a query for
                      ** the current default journal mode (which may be different to
                      ** the journal-mode of the main database).
                      */
                                                eMode = db.dfltJournalMode;
                                            }
                                            else
                                            {
                                                Pager pPager;
                                                if (pId2.n == 0)
                                                {
                                                    /* This indicates that no database name was specified as part
                        ** of the PRAGMA command. In this case the journal-mode must be
                        ** set on all attached databases, as well as the main db file.
                        **
                        ** Also, the sqlite3.dfltJournalMode variable is set so that
                        ** any subsequently attached databases also use the specified
                        ** journal mode.
                        */
                                                    int ii;
                                                    Debug.Assert(pDb == db.aDb[0]);
                                                    for (ii = 1; ii < db.nDb; ii++)
                                                    {
                                                        if (db.aDb[ii].pBt != null)
                                                        {
                                                            pPager = sqlite3BtreePager(db.aDb[ii].pBt);
                                                            sqlite3PagerJournalMode(pPager, eMode);
                                                        }
                                                    }
                                                    db.dfltJournalMode = (byte) eMode;
                                                }
                                                pPager = sqlite3BtreePager(pDb.pBt);
                                                eMode = sqlite3PagerJournalMode(pPager, eMode);
                                            }
                                            Debug.Assert(eMode == PagerJournalMode.PAGER_JOURNALMODE_DELETE
                                                         || eMode == PagerJournalMode.PAGER_JOURNALMODE_TRUNCATE
                                                         || eMode == PagerJournalMode.PAGER_JOURNALMODE_PERSIST
                                                         || eMode == PagerJournalMode.PAGER_JOURNALMODE_OFF
                                                         || eMode == PagerJournalMode.PAGER_JOURNALMODE_MEMORY);
                                            VdbeAux.VdbeSetNumCols(v, 1);
                                            VdbeAux.VdbeSetColName(v, 0, VdbeColnameType.COLNAME_NAME, "journal_mode", Const.SQLITE_STATIC);
                                            VdbeAux.VdbeAddOp4(v, OPCode.OP_String8, 0, 1, 0,
                                                              azModeName[eMode], P4Type.P4_STATIC);
                                            VdbeAux.VdbeAddOp2(v, OPCode.OP_ResultRow, 1, 1);
                                        }
                                        else

                                            /*
                    **  PRAGMA [database.]journal_size_limit
                    **  PRAGMA [database.]journal_size_limit=N
                    **
                    ** Get or set the size limit on rollback journal files.
                    */ if (Utility.Sqlite3StrICmp(zLeft, "journal_size_limit") == 0)
                                            {
                                                Pager pPager = sqlite3BtreePager(pDb.pBt);
                                                long iLimit = -2;
                                                if (!String.IsNullOrEmpty(zRight))
                                                {
                                                    Utility.Sqlite3Atoi64(zRight, ref iLimit);
                                                    if (iLimit < -1) iLimit = -1;
                                                }
                                                iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
                                                returnSingleInt(pParse, "journal_size_limit", iLimit);
                                            }
                                            else

#endif
                                                // * SQLITE_OMIT_PAGER_PRAGMAS */

                                                /*
**  PRAGMA [database.]auto_vacuum
**  PRAGMA [database.]auto_vacuum=N
**
** Get or set the value of the database 'auto-vacuum' parameter.
** The value is one of:  0 NONE 1 FULL 2 INCREMENTAL
*/
#if !SQLITE_OMIT_AUTOVACUUM
                                                if (Utility.Sqlite3StrICmp(zLeft, "auto_vacuum") == 0)
                                                {
                                                    Btree pBt = pDb.pBt;
                                                    Debug.Assert(pBt != null);
                                                    if (Prepare.ReadSchema(pParse) != 0)
                                                    {
                                                        goto pragma_out;
                                                    }
                                                    if (null == zRight)
                                                    {
                                                        int auto_vacuum;
                                                        if (UnitTest.ALWAYS(pBt))
                                                        {
                                                            auto_vacuum = sqlite3BtreeGetAutoVacuum(pBt);
                                                        }
                                                        else
                                                        {
                                                            auto_vacuum = Const.SQLITE_DEFAULT_AUTOVACUUM;
                                                        }
                                                        returnSingleInt(pParse, "auto_vacuum", auto_vacuum);
                                                    }
                                                    else
                                                    {
                                                        int eAuto = getAutoVacuum(zRight);
                                                        Debug.Assert(eAuto >= 0 && eAuto <= 2);
                                                        db.nextAutovac = (byte) eAuto;
                                                        if (UnitTest.ALWAYS(eAuto >= 0))
                                                        {
                                                            /* Call SetAutoVacuum() to set initialize the internal auto and
                            ** incr-vacuum flags. This is required in case this connection
                            ** creates the database file. It is important that it is created
                            ** as an auto-vacuum capable db.
                            */
                                                            int rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto);
                                                            if (rc == StatusCode.SQLITE_OK && (eAuto == 1 || eAuto == 2))
                                                            {
                                                                /* When setting the auto_vacuum mode to either "full" or
                              ** "incremental", write the value of meta[6] in the database
                              ** file. Before writing to meta[6], check that meta[3] indicates
                              ** that this really is an auto-vacuum capable database.
                              */
                                                                var setMeta6 = new[]
                                                                                   {
                                                                                       new VdbeOpList(OPCode.OP_Transaction, 0,
                                                                                                      1, 0), /* 0 */
                                                                                       new VdbeOpList(OPCode.OP_ReadCookie, 0,
                                                                                                      1,
                                                                                                      BtreeMeta.BTREE_LARGEST_ROOT_PAGE)
                                                                                       , /* 1 */
                                                                                       new VdbeOpList(OPCode.OP_If, 1, 0, 0),
                                                                                       /* 2 */
                                                                                       new VdbeOpList(OPCode.OP_Halt, StatusCode.SQLITE_OK,
                                                                                                      OnConstraintError.OE_Abort, 0),
                                                                                       /* 3 */
                                                                                       new VdbeOpList(OPCode.OP_Integer, 0, 1,
                                                                                                      0), /* 4 */
                                                                                       new VdbeOpList(OPCode.OP_SetCookie, 0,
                                                                                                      BtreeMeta.BTREE_INCR_VACUUM,
                                                                                                      1), /* 5 */
                                                                                   };
                                                                int iAddr;
                                                                iAddr = VdbeAux.VdbeAddOpList(v, Utility.ArraySize(setMeta6),
                                                                                             setMeta6);
                                                                VdbeAux.VdbeChangeP1(v, iAddr, iDb);
                                                                VdbeAux.VdbeChangeP1(v, iAddr + 1, iDb);
                                                                VdbeAux.VdbeChangeP2(v, iAddr + 2, iAddr + 4);
                                                                VdbeAux.VdbeChangeP1(v, iAddr + 4, eAuto - 1);
                                                                VdbeAux.VdbeChangeP1(v, iAddr + 5, iDb);
                                                                VdbeAux.VdbeUsesBtree(v, iDb);
                                                            }
                                                        }
                                                    }
                                                }
                                                else
#endif

                                                    /*
**  PRAGMA [database.]incremental_vacuum(N)
**
** Do N steps of incremental vacuuming on a database.
*/
#if !SQLITE_OMIT_AUTOVACUUM
                                                    if (Utility.Sqlite3StrICmp(zLeft, "incremental_vacuum") == 0)
                                                    {
                                                        int iLimit = 0, addr;
                                                        if (Prepare.ReadSchema(pParse) != 0)
                                                        {
                                                            goto pragma_out;
                                                        }
                                                        if (zRight == null || !Utility.Sqlite3GetInt32(zRight, ref iLimit) ||
                                                            iLimit <= 0)
                                                        {
                                                            iLimit = 0x7fffffff;
                                                        }
                                                        Build.BeginWriteOperation(pParse, 0, iDb);
                                                        VdbeAux.VdbeAddOp2(v, OPCode.OP_Integer, iLimit, 1);
                                                        addr = VdbeAux.VdbeAddOp1(v, OPCode.OP_IncrVacuum, iDb);
                                                        VdbeAux.VdbeAddOp1(v, OPCode.OP_ResultRow, 1);
                                                        VdbeAux.VdbeAddOp2(v, OPCode.OP_AddImm, 1, -1);
                                                        VdbeAux.VdbeAddOp2(v, OPCode.OP_IfPos, 1, addr);
                                                        VdbeAux.VdbeJumpHere(v, addr);
                                                    }
                                                    else
#endif

#if !SQLITE_OMIT_PAGER_PRAGMAS
                                                        /*
**  PRAGMA [database.]cache_size
**  PRAGMA [database.]cache_size=N
**
** The first form reports the current local setting for the
** page cache size.  The local setting can be different from
** the persistent cache size value that is stored in the database
** file itself.  The value returned is the maximum number of
** pages in the page cache.  The second form sets the local
** page cache size value.  It does not change the persistent
** cache size stored on the disk so the cache size will revert
** to its default value when the database is closed and reopened.
** N should be a positive integer.
*/ if (Utility.Sqlite3StrICmp(zLeft, "cache_size") == 0)
                                                        {
                                                            if (Prepare.ReadSchema(pParse) != 0) goto pragma_out;
                                                            if (null == zRight)
                                                            {
                                                                returnSingleInt(pParse, "cache_size",
                                                                                pDb.pSchema.cache_size);
                                                            }
                                                            else
                                                            {
                                                                int size = Custom.Atoi(zRight);
                                                                if (size < 0) size = -size;
                                                                pDb.pSchema.cache_size = size;
                                                                sqlite3BtreeSetCacheSize(pDb.pBt, pDb.pSchema.cache_size);
                                                            }
                                                        }
                                                        else

                                                            /*
                            **   PRAGMA temp_store
                            **   PRAGMA temp_store = "default"|"memory"|"file"
                            **
                            ** Return or set the local value of the temp_store flag.  Changing
                            ** the local value does not make changes to the disk file and the default
                            ** value will be restored the next time the database is opened.
                            **
                            ** Note that it is possible for the library compile-time options to
                            ** override this setting
                            */ if (Utility.Sqlite3StrICmp(zLeft, "temp_store") == 0)
                                                            {
                                                                if (zRight == null)
                                                                {
                                                                    returnSingleInt(pParse, "temp_store", db.temp_store);
                                                                }
                                                                else
                                                                {
                                                                    changeTempStorage(pParse, zRight);
                                                                }
                                                            }
                                                            else

                                                                /*
                              **   PRAGMA temp_store_directory
                              **   PRAGMA temp_store_directory = ""|"directory_name"
                              **
                              ** Return or set the local value of the temp_store_directory flag.  Changing
                              ** the value sets a specific directory to be used for temporary files.
                              ** Setting to a null string reverts to the default temporary directory search.
                              ** If temporary directory is changed, then invalidateTempStorage.
                              **
                              */ if (Utility.Sqlite3StrICmp(zLeft, "temp_store_directory") == 0)
                                                                {
                                                                    if (null == zRight)
                                                                    {
                                                                        if (sqlite3_temp_directory != "")
                                                                        {
                                                                            VdbeAux.VdbeSetNumCols(v, 1);
                                                                            VdbeAux.VdbeSetColName(v, 0, VdbeColnameType.COLNAME_NAME,
                                                                                                  "temp_store_directory",
                                                                                                  Const.SQLITE_STATIC);
                                                                            VdbeAux.VdbeAddOp4(v, OPCode.OP_String8, 0, 1, 0,
                                                                                              sqlite3_temp_directory, 0);
                                                                            VdbeAux.VdbeAddOp2(v, OPCode.OP_ResultRow, 1, 1);
                                                                        }
                                                                    }
                                                                    else
                                                                    {
#if !SQLITE_OMIT_WSD
                                                                        if (zRight.Length > 0)
                                                                        {
                                                                            int rc;
                                                                            int res = 0;
                                                                            rc = sqlite3OsAccess(db.pVfs, zRight,
                                                                                                 AccessFlag.SQLITE_ACCESS_READWRITE,
                                                                                                 ref res);
                                                                            if (rc != StatusCode.SQLITE_OK || res == 0)
                                                                            {
                                                                                Utility.Sqlite3ErrorMsg(pParse,
                                                                                                "not a writable directory");
                                                                                goto pragma_out;
                                                                            }
                                                                        }
                                                                        if (SQLITE_TEMP_STORE == 0
                                                                            ||
                                                                            (SQLITE_TEMP_STORE == 1 &&
                                                                             db.temp_store <= 1)
                                                                            ||
                                                                            (SQLITE_TEMP_STORE == 2 &&
                                                                             db.temp_store == 1)
                                                                            )
                                                                        {
                                                                            invalidateTempStorage(pParse);
                                                                        }
                                                                        //Malloc.sqlite3_free( ref sqlite3_temp_directory );
                                                                        if (zRight.Length > 0)
                                                                        {
                                                                            sqlite3_temp_directory = zRight;
                                                                                //sqlite3DbStrDup(0, zRight);
                                                                        }
                                                                        else
                                                                        {
                                                                            sqlite3_temp_directory = "";
                                                                        }
#endif
                                                                        //* SQLITE_OMIT_WSD */
                                                                    }
                                                                }
                                                                else

#if !(SQLITE_ENABLE_LOCKING_STYLE)
#  if (__APPLE__)
//#    define SQLITE_ENABLE_LOCKING_STYLE 1
#  else
                                                                    //#    define SQLITE_ENABLE_LOCKING_STYLE 0
#  endif
#endif
#if SQLITE_ENABLE_LOCKING_STYLE
/*
**   PRAGMA [database.]lock_proxy_file
**   PRAGMA [database.]lock_proxy_file = ":auto:"|"lock_file_path"
**
** Return or set the value of the lock_proxy_file flag.  Changing
** the value sets a specific file to be used for database access locks.
**
*/
if ( Utility.Sqlite3StrICmp( zLeft, "lock_proxy_file" ) == 0 )
{
if ( zRight !="")
{
Pager pPager = sqlite3BtreePager( pDb.pBt );
int proxy_file_path = 0;
sqlite3_file pFile = sqlite3PagerFile( pPager );
sqlite3OsFileControl( pFile, SQLITE_GET_LOCKPROXYFILE,
ref proxy_file_path );

if ( proxy_file_path!=0 )
{
VdbeAux.VdbeSetNumCols( v, 1 );
VdbeAux.VdbeSetColName( v, 0, VdbeColnameType.COLNAME_NAME,
"lock_proxy_file", Const.SQLITE_STATIC );
VdbeAux.VdbeAddOp4( v, OPCode.OP_String8, 0, 1, 0, proxy_file_path, 0 );
VdbeAux.VdbeAddOp2( v, OPCode.OP_ResultRow, 1, 1 );
}
}
else
{
Pager pPager = sqlite3BtreePager( pDb.pBt );
sqlite3_file pFile = sqlite3PagerFile( pPager );
int res;
int iDummy = 0;
if ( zRight[0]!=0 )
{
iDummy = zRight[0];
res = sqlite3OsFileControl( pFile, SQLITE_SET_LOCKPROXYFILE,
ref iDummy );
}
else
{
res = sqlite3OsFileControl( pFile, SQLITE_SET_LOCKPROXYFILE,
ref iDummy );
}
if ( res != StatusCode.SQLITE_OK )
{
Utility.Sqlite3ErrorMsg( pParse, "failed to set lock proxy file" );
goto pragma_out;
}
}
}
else
#endif
                                                                    //* SQLITE_ENABLE_LOCKING_STYLE */

                                                                    /*
**   PRAGMA [database.]synchronous
**   PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL
**
** Return or set the local value of the synchronous flag.  Changing
** the local value does not make changes to the disk file and the
** default value will be restored the next time the database is
** opened.
*/ if (Utility.Sqlite3StrICmp(zLeft, "synchronous") == 0)
                                                                    {
                                                                        if (Prepare.ReadSchema(pParse) != 0)
                                                                            goto pragma_out;
                                                                        if (null == zRight)
                                                                        {
                                                                            returnSingleInt(pParse, "synchronous",
                                                                                            pDb.safety_level - 1);
                                                                        }
                                                                        else
                                                                        {
                                                                            if (0 == db.autoCommit)
                                                                            {
                                                                                Utility.Sqlite3ErrorMsg(pParse,
                                                                                                "Safety level may not be changed inside a transaction");
                                                                            }
                                                                            else
                                                                            {
                                                                                pDb.safety_level =
                                                                                    (byte) (getSafetyLevel(zRight) + 1);
                                                                            }
                                                                        }
                                                                    }
                                                                    else
#endif
                                                                        // * SQLITE_OMIT_PAGER_PRAGMAS */

#if !SQLITE_OMIT_FLAG_PRAGMAS
                                                                        if (flagPragma(pParse, zLeft, zRight) != 0)
                                                                        {
                                                                            /* The flagPragma() subroutine also generates any necessary code
                                    ** there is nothing more to do here */
                                                                        }
                                                                        else
#endif
                                                                            // * SQLITE_OMIT_FLAG_PRAGMAS */

#if !SQLITE_OMIT_SCHEMA_PRAGMAS
                                                                            /*
**   PRAGMA table_info(<table>)
**
** Return a single row for each column of the named table. The columns of
** the returned data set are:
**
** cid:        Column id (numbered from left to right, starting at 0)
** name:       Column name
** type:       Column declaration type.
** notnull:    True if 'NOT NULL' is part of column declaration
** dflt_value: The default value for the column, if any.
*/ if (Utility.Sqlite3StrICmp(zLeft, "table_info") == 0 &&
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 zRight != null)
                                                                            {
                                                                                Table pTab;
                                                                                if (Prepare.ReadSchema(pParse) != 0)
                                                                                    goto pragma_out;
                                                                                pTab = Build.FindTable(db, zRight, zDb);
                                                                                if (pTab != null)
                                                                                {
                                                                                    int i;
                                                                                    int nHidden = 0;
                                                                                    Column pCol;
                                                                                    VdbeAux.VdbeSetNumCols(v, 6);
                                                                                    pParse.nMem = 6;
                                                                                    VdbeAux.VdbeSetColName(v, 0,
                                                                                                          VdbeColnameType.COLNAME_NAME,
                                                                                                          "cid",
                                                                                                          Const.SQLITE_STATIC);
                                                                                    VdbeAux.VdbeSetColName(v, 1,
                                                                                                          VdbeColnameType.COLNAME_NAME,
                                                                                                          "name",
                                                                                                          Const.SQLITE_STATIC);
                                                                                    VdbeAux.VdbeSetColName(v, 2,
                                                                                                          VdbeColnameType.COLNAME_NAME,
                                                                                                          "type",
                                                                                                          Const.SQLITE_STATIC);
                                                                                    VdbeAux.VdbeSetColName(v, 3,
                                                                                                          VdbeColnameType.COLNAME_NAME,
                                                                                                          "notnull",
                                                                                                          Const.SQLITE_STATIC);
                                                                                    VdbeAux.VdbeSetColName(v, 4,
                                                                                                          VdbeColnameType.COLNAME_NAME,
                                                                                                          "dflt_value",
                                                                                                          Const.SQLITE_STATIC);
                                                                                    VdbeAux.VdbeSetColName(v, 5,
                                                                                                          VdbeColnameType.COLNAME_NAME,
                                                                                                          "pk",
                                                                                                          Const.SQLITE_STATIC);
                                                                                    Build.ViewGetColumnNames(pParse,
                                                                                                              pTab);
                                                                                    for (i = 0; i < pTab.nCol; i++)
                                                                                        //, pCol++)
                                                                                    {
                                                                                        pCol = pTab.aCol[i];
                                                                                        if (Utility.IsHiddenColumn(pCol))
                                                                                        {
                                                                                            nHidden++;
                                                                                            continue;
                                                                                        }
                                                                                        VdbeAux.VdbeAddOp2(v, OPCode.OP_Integer,
                                                                                                          i - nHidden, 1);
                                                                                        VdbeAux.VdbeAddOp4(v, OPCode.OP_String8,
                                                                                                          0, 2, 0,
                                                                                                          pCol.zName, 0);
                                                                                        VdbeAux.VdbeAddOp4(v, OPCode.OP_String8,
                                                                                                          0, 3, 0,
                                                                                                          pCol.zType !=
                                                                                                          null
                                                                                                              ? pCol.
                                                                                                                    zType
                                                                                                              : "", 0);
                                                                                        VdbeAux.VdbeAddOp2(v, OPCode.OP_Integer,
                                                                                                          (pCol.notNull !=
                                                                                                           0
                                                                                                               ? 1
                                                                                                               : 0), 4);
                                                                                        if (pCol.zDflt != null)
                                                                                        {
                                                                                            VdbeAux.VdbeAddOp4(v,
                                                                                                              OPCode.OP_String8,
                                                                                                              0, 5, 0,
                                                                                                              pCol.zDflt,
                                                                                                              0);
                                                                                        }
                                                                                        else
                                                                                        {
                                                                                            VdbeAux.VdbeAddOp2(v, OPCode.OP_Null,
                                                                                                              0, 5);
                                                                                        }
                                                                                        VdbeAux.VdbeAddOp2(v, OPCode.OP_Integer,
                                                                                                          pCol.isPrimKey !=
                                                                                                          0
                                                                                                              ? 1
                                                                                                              : 0, 6);
                                                                                        VdbeAux.VdbeAddOp2(v,
                                                                                                          OPCode.OP_ResultRow,
                                                                                                          1, 6);
                                                                                    }
                                                                                }
                                                                            }
                                                                            else if (
                                                                                Utility.Sqlite3StrICmp(zLeft, "index_info") ==
                                                                                0 && zRight != null)
                                                                            {
                                                                                Index pIdx;
                                                                                Table pTab;
                                                                                if (Prepare.ReadSchema(pParse) != 0)
                                                                                    goto pragma_out;
                                                                                pIdx = Build.FindIndex(db, zRight,
                                                                                                        zDb);
                                                                                if (pIdx != null)
                                                                                {
                                                                                    int i;
                                                                                    pTab = pIdx.pTable;
                                                                                    VdbeAux.VdbeSetNumCols(v, 3);
                                                                                    pParse.nMem = 3;
                                                                                    VdbeAux.VdbeSetColName(v, 0,
                                                                                                          VdbeColnameType.COLNAME_NAME,
                                                                                                          "seqno",
                                                                                                          Const.SQLITE_STATIC);
                                                                                    VdbeAux.VdbeSetColName(v, 1,
                                                                                                          VdbeColnameType.COLNAME_NAME,
                                                                                                          "cid",
                                                                                                          Const.SQLITE_STATIC);
                                                                                    VdbeAux.VdbeSetColName(v, 2,
                                                                                                          VdbeColnameType.COLNAME_NAME,
                                                                                                          "name",
                                                                                                          Const.SQLITE_STATIC);
                                                                                    for (i = 0;
                                                                                         i < pIdx.nColumn;
                                                                                         i++)
                                                                                    {
                                                                                        int cnum = pIdx.aiColumn[i];
                                                                                        VdbeAux.VdbeAddOp2(v,
                                                                                                          OPCode.OP_Integer,
                                                                                                          i, 1);
                                                                                        VdbeAux.VdbeAddOp2(v,
                                                                                                          OPCode.OP_Integer,
                                                                                                          cnum, 2);
                                                                                        Debug.Assert(pTab.nCol >
                                                                                                     cnum);
                                                                                        VdbeAux.VdbeAddOp4(v,
                                                                                                          OPCode.OP_String8,
                                                                                                          0, 3, 0,
                                                                                                          pTab.aCol[
                                                                                                              cnum].
                                                                                                              zName,
                                                                                                          0);
                                                                                        VdbeAux.VdbeAddOp2(v,
                                                                                                          OPCode.OP_ResultRow,
                                                                                                          1, 3);
                                                                                    }
                                                                                }
                                                                            }
                                                                            else if (
                                                                                Utility.Sqlite3StrICmp(zLeft,
                                                                                               "index_list") ==
                                                                                0 && zRight != null)
                                                                            {
                                                                                Index pIdx;
                                                                                Table pTab;
                                                                                if (Prepare.ReadSchema(pParse) !=
                                                                                    0) goto pragma_out;
                                                                                pTab = Build.FindTable(db,
                                                                                                        zRight,
                                                                                                        zDb);
                                                                                if (pTab != null)
                                                                                {
                                                                                    v = SelectHelper.GetVdbe(pParse);
                                                                                    pIdx = pTab.pIndex;
                                                                                    if (pIdx != null)
                                                                                    {
                                                                                        int i = 0;
                                                                                        VdbeAux.VdbeSetNumCols(
                                                                                            v, 3);
                                                                                        pParse.nMem = 3;
                                                                                        VdbeAux.VdbeSetColName(
                                                                                            v, 0, VdbeColnameType.COLNAME_NAME,
                                                                                            "seq", Const.SQLITE_STATIC);
                                                                                        VdbeAux.VdbeSetColName(
                                                                                            v, 1, VdbeColnameType.COLNAME_NAME,
                                                                                            "name",
                                                                                            Const.SQLITE_STATIC);
                                                                                        VdbeAux.VdbeSetColName(
                                                                                            v, 2, VdbeColnameType.COLNAME_NAME,
                                                                                            "unique",
                                                                                            Const.SQLITE_STATIC);
                                                                                        while (pIdx != null)
                                                                                        {
                                                                                            VdbeAux.VdbeAddOp2(
                                                                                                v, OPCode.OP_Integer, i,
                                                                                                1);
                                                                                            VdbeAux.VdbeAddOp4(
                                                                                                v, OPCode.OP_String8, 0,
                                                                                                2, 0, pIdx.zName,
                                                                                                0);
                                                                                            VdbeAux.VdbeAddOp2(
                                                                                                v, OPCode.OP_Integer,
                                                                                                (pIdx.onError !=
                                                                                                 OnConstraintError.OE_None)
                                                                                                    ? 1
                                                                                                    : 0, 3);
                                                                                            VdbeAux.VdbeAddOp2(
                                                                                                v, OPCode.OP_ResultRow,
                                                                                                1, 3);
                                                                                            ++i;
                                                                                            pIdx = pIdx.pNext;
                                                                                        }
                                                                                    }
                                                                                }
                                                                            }
                                                                            else if (
                                                                                Utility.Sqlite3StrICmp(zLeft,
                                                                                               "database_list") ==
                                                                                0)
                                                                            {
                                                                                int i;
                                                                                if (
                                                                                    Prepare.ReadSchema(pParse) !=
                                                                                    0) goto pragma_out;
                                                                                VdbeAux.VdbeSetNumCols(v, 3);
                                                                                pParse.nMem = 3;
                                                                                VdbeAux.VdbeSetColName(v, 0,
                                                                                                      VdbeColnameType.COLNAME_NAME,
                                                                                                      "seq",
                                                                                                      Const.SQLITE_STATIC);
                                                                                VdbeAux.VdbeSetColName(v, 1,
                                                                                                      VdbeColnameType.COLNAME_NAME,
                                                                                                      "name",
                                                                                                      Const.SQLITE_STATIC);
                                                                                VdbeAux.VdbeSetColName(v, 2,
                                                                                                      VdbeColnameType.COLNAME_NAME,
                                                                                                      "file",
                                                                                                      Const.SQLITE_STATIC);
                                                                                for (i = 0; i < db.nDb; i++)
                                                                                {
                                                                                    if (db.aDb[i].pBt ==
                                                                                        null) continue;
                                                                                    Debug.Assert(
                                                                                        db.aDb[i].zName !=
                                                                                        null);
                                                                                    VdbeAux.VdbeAddOp2(v,
                                                                                                      OPCode.OP_Integer,
                                                                                                      i, 1);
                                                                                    VdbeAux.VdbeAddOp4(v,
                                                                                                      OPCode.OP_String8,
                                                                                                      0, 2,
                                                                                                      0,
                                                                                                      db.aDb
                                                                                                          [i
                                                                                                          ].
                                                                                                          zName,
                                                                                                      0);
                                                                                    VdbeAux.VdbeAddOp4(v,
                                                                                                      OPCode.OP_String8,
                                                                                                      0, 3,
                                                                                                      0,
                                                                                                      sqlite3BtreeGetFilename
                                                                                                          (db
                                                                                                               .
                                                                                                               aDb
                                                                                                               [
                                                                                                                   i
                                                                                                               ]
                                                                                                               .
                                                                                                               pBt),
                                                                                                      0);
                                                                                    VdbeAux.VdbeAddOp2(v,
                                                                                                      OPCode.OP_ResultRow,
                                                                                                      1, 3);
                                                                                }
                                                                            }
                                                                            else if (
                                                                                Utility.Sqlite3StrICmp(zLeft,
                                                                                               "collation_list") ==
                                                                                0)
                                                                            {
                                                                                int i = 0;
                                                                                HashElem p;
                                                                                VdbeAux.VdbeSetNumCols(
                                                                                    v, 2);
                                                                                pParse.nMem = 2;
                                                                                VdbeAux.VdbeSetColName(
                                                                                    v, 0, VdbeColnameType.COLNAME_NAME,
                                                                                    "seq", Const.SQLITE_STATIC);
                                                                                VdbeAux.VdbeSetColName(
                                                                                    v, 1, VdbeColnameType.COLNAME_NAME,
                                                                                    "name",
                                                                                    Const.SQLITE_STATIC);
                                                                                for (
                                                                                    p =
                                                                                    db.aCollSeq.first;
                                                                                    p != null;
                                                                                    p = p.next)
                                                                                    //( p = HashHelper.HashFirst( db.aCollSeq ) ; p; p = HashHelper.HashNext( p ) )
                                                                                {
                                                                                    CollSeq pColl =
                                                                                        ((CollSeq[])
                                                                                         p.data)[0];
                                                                                        // HashHelper.HashData( p );
                                                                                    VdbeAux.VdbeAddOp2(
                                                                                        v, OPCode.OP_Integer,
                                                                                        i++, 1);
                                                                                    VdbeAux.VdbeAddOp4(
                                                                                        v, OPCode.OP_String8, 0,
                                                                                        2, 0,
                                                                                        pColl.zName, 0);
                                                                                    VdbeAux.VdbeAddOp2(
                                                                                        v, OPCode.OP_ResultRow,
                                                                                        1, 2);
                                                                                }
                                                                            }
                                                                            else
#endif
                                                                                // * SQLITE_OMIT_SCHEMA_PRAGMAS */

#if !SQLITE_OMIT_FOREIGN_KEY
                                                                                if (
                                                                                    Utility.Sqlite3StrICmp(
                                                                                        zLeft,
                                                                                        "foreign_key_list") ==
                                                                                    0 && zRight != null)
                                                                                {
                                                                                    FKey pFK;
                                                                                    Table pTab;
                                                                                    if (
                                                                                        Prepare.ReadSchema
                                                                                            (pParse) !=
                                                                                        0)
                                                                                        goto pragma_out;
                                                                                    pTab =
                                                                                        Build.FindTable
                                                                                            (db, zRight,
                                                                                             zDb);
                                                                                    if (pTab != null)
                                                                                    {
                                                                                        v =
                                                                                            SelectHelper.GetVdbe
                                                                                                (pParse);
                                                                                        pFK = pTab.pFKey;
                                                                                        if (pFK != null)
                                                                                        {
                                                                                            int i = 0;
                                                                                            VdbeAux.VdbeSetNumCols
                                                                                                (v, 8);
                                                                                            pParse.nMem
                                                                                                = 8;
                                                                                            VdbeAux.VdbeSetColName
                                                                                                (v, 0,
                                                                                                 VdbeColnameType.COLNAME_NAME,
                                                                                                 "id",
                                                                                                 Const.SQLITE_STATIC);
                                                                                            VdbeAux.VdbeSetColName
                                                                                                (v, 1,
                                                                                                 VdbeColnameType.COLNAME_NAME,
                                                                                                 "seq",
                                                                                                 Const.SQLITE_STATIC);
                                                                                            VdbeAux.VdbeSetColName
                                                                                                (v, 2,
                                                                                                 VdbeColnameType.COLNAME_NAME,
                                                                                                 "table",
                                                                                                 Const.SQLITE_STATIC);
                                                                                            VdbeAux.VdbeSetColName
                                                                                                (v, 3,
                                                                                                 VdbeColnameType.COLNAME_NAME,
                                                                                                 "from",
                                                                                                 Const.SQLITE_STATIC);
                                                                                            VdbeAux.VdbeSetColName
                                                                                                (v, 4,
                                                                                                 VdbeColnameType.COLNAME_NAME,
                                                                                                 "to",
                                                                                                 Const.SQLITE_STATIC);
                                                                                            VdbeAux.VdbeSetColName
                                                                                                (v, 5,
                                                                                                 VdbeColnameType.COLNAME_NAME,
                                                                                                 "on_update",
                                                                                                 Const.SQLITE_STATIC);
                                                                                            VdbeAux.VdbeSetColName
                                                                                                (v, 6,
                                                                                                 VdbeColnameType.COLNAME_NAME,
                                                                                                 "on_delete",
                                                                                                 Const.SQLITE_STATIC);
                                                                                            VdbeAux.VdbeSetColName
                                                                                                (v, 7,
                                                                                                 VdbeColnameType.COLNAME_NAME,
                                                                                                 "match",
                                                                                                 Const.SQLITE_STATIC);
                                                                                            while (
                                                                                                pFK !=
                                                                                                null)
                                                                                            {
                                                                                                int j;
                                                                                                for (
                                                                                                    j =
                                                                                                    0;
                                                                                                    j <
                                                                                                    pFK.
                                                                                                        nCol;
                                                                                                    j++)
                                                                                                {
                                                                                                    string
                                                                                                        zCol
                                                                                                            =
                                                                                                            pFK
                                                                                                                .
                                                                                                                aCol
                                                                                                                [
                                                                                                                    j
                                                                                                                ]
                                                                                                                .
                                                                                                                zCol;
                                                                                                    string
                                                                                                        zOnDelete
                                                                                                            =
                                                                                                            actionName
                                                                                                                (pFK
                                                                                                                     .
                                                                                                                     aAction
                                                                                                                     [
                                                                                                                         0
                                                                                                                     ]);
                                                                                                    string
                                                                                                        zOnUpdate
                                                                                                            =
                                                                                                            actionName
                                                                                                                (pFK
                                                                                                                     .
                                                                                                                     aAction
                                                                                                                     [
                                                                                                                         1
                                                                                                                     ]);
                                                                                                    VdbeAux.VdbeAddOp2
                                                                                                        (v,
                                                                                                         OPCode.OP_Integer,
                                                                                                         i,
                                                                                                         1);
                                                                                                    VdbeAux.VdbeAddOp2
                                                                                                        (v,
                                                                                                         OPCode.OP_Integer,
                                                                                                         j,
                                                                                                         2);
                                                                                                    VdbeAux.VdbeAddOp4
                                                                                                        (v,
                                                                                                         OPCode.OP_String8,
                                                                                                         0,
                                                                                                         3,
                                                                                                         0,
                                                                                                         pFK
                                                                                                             .
                                                                                                             zTo,
                                                                                                         0);
                                                                                                    VdbeAux.VdbeAddOp4
                                                                                                        (v,
                                                                                                         OPCode.OP_String8,
                                                                                                         0,
                                                                                                         4,
                                                                                                         0,
                                                                                                         pTab
                                                                                                             .
                                                                                                             aCol
                                                                                                             [
                                                                                                                 pFK
                                                                                                                     .
                                                                                                                     aCol
                                                                                                                     [
                                                                                                                         j
                                                                                                                     ]
                                                                                                                     .
                                                                                                                     iFrom
                                                                                                             ]
                                                                                                             .
                                                                                                             zName,
                                                                                                         0);
                                                                                                    VdbeAux.VdbeAddOp4
                                                                                                        (v,
                                                                                                         zCol !=
                                                                                                         null
                                                                                                             ? OPCode.OP_String8
                                                                                                             : OPCode.OP_Null,
                                                                                                         0,
                                                                                                         5,
                                                                                                         0,
                                                                                                         zCol,
                                                                                                         0);
                                                                                                    VdbeAux.VdbeAddOp4
                                                                                                        (v,
                                                                                                         OPCode.OP_String8,
                                                                                                         0,
                                                                                                         6,
                                                                                                         0,
                                                                                                         zOnUpdate,
                                                                                                         0);
                                                                                                    VdbeAux.VdbeAddOp4
                                                                                                        (v,
                                                                                                         OPCode.OP_String8,
                                                                                                         0,
                                                                                                         7,
                                                                                                         0,
                                                                                                         zOnDelete,
                                                                                                         0);
                                                                                                    VdbeAux.VdbeAddOp4
                                                                                                        (v,
                                                                                                         OPCode.OP_String8,
                                                                                                         0,
                                                                                                         8,
                                                                                                         0,
                                                                                                         "NONE",
                                                                                                         0);
                                                                                                    VdbeAux.VdbeAddOp2
                                                                                                        (v,
                                                                                                         OPCode.OP_ResultRow,
                                                                                                         1,
                                                                                                         8);
                                                                                                }
                                                                                                ++i;
                                                                                                pFK =
                                                                                                    pFK.
                                                                                                        pNextFrom;
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                }
                                                                                else
#endif
                                                                                    // * !SQLITE_OMIT_FOREIGN_KEY) */

#if !NDEBUG
                                                if ( Utility.Sqlite3StrICmp( zLeft, "parser_trace" ) == 0 )
                                                {
                                                  if ( zRight != null )
                                                  {
                                                    if ( getBoolean( zRight ) != 0 )
                                                    {
                                                      sqlite3ParserTrace( Console.Out, "parser: " );
                                                    }
                                                    else
                                                    {
                                                      sqlite3ParserTrace( null, "" );
                                                    }
                                                  }
                                                }
                                                else
#endif

                                                                                    /* Reinstall the LIKE and GLOB functions.  The variant of LIKE
** used will be case sensitive or not depending on the RHS.
*/ if (
                                                                                        Utility.Sqlite3StrICmp(
                                                                                            zLeft,
                                                                                            "case_sensitive_like") ==
                                                                                        0)
                                                                                    {
                                                                                        if (zRight !=
                                                                                            null)
                                                                                        {
                                                                                            sqlite3RegisterLikeFunctions
                                                                                                (db,
                                                                                                 getBoolean
                                                                                                     (zRight));
                                                                                        }
                                                                                    }
                                                                                    else

#if !SQLITE_INTEGRITY_CHECK_ERROR_MAX
                                                                                        //const int SQLITE_INTEGRITY_CHECK_ERROR_MAX = 100;
#endif

#if !SQLITE_OMIT_INTEGRITY_CHECK
                                                                                        /* Pragma "quick_check" is an experimental reduced version of
** integrity_check designed to detect most database corruption
** without most of the overhead of a full integrity-check.
*/ if (
                                                                                            Utility.Sqlite3StrICmp
                                                                                                (zLeft,
                                                                                                 "integrity_check") ==
                                                                                            0
                                                                                            ||
                                                                                            Utility.Sqlite3StrICmp
                                                                                                (zLeft,
                                                                                                 "quick_check") ==
                                                                                            0
                                                                                            )
                                                                                        {
                                                                                            const int
                                                                                                SQLITE_INTEGRITY_CHECK_ERROR_MAX
                                                                                                    =
                                                                                                    100;
                                                                                            int i,
                                                                                                j,
                                                                                                addr,
                                                                                                mxErr;

                                                                                            /* Code that appears at the end of the integrity check.  If no error
                                                      ** messages have been generated, output OK.  Otherwise output the
                                                      ** error message
                                                      */
                                                                                            var endCode
                                                                                                = new[]
                                                                                                      {
                                                                                                          new VdbeOpList
                                                                                                              (OPCode.OP_AddImm,
                                                                                                               1,
                                                                                                               0,
                                                                                                               0)
                                                                                                          ,
                                                                                                          /* 0 */
                                                                                                          new VdbeOpList
                                                                                                              (OPCode.OP_IfNeg,
                                                                                                               1,
                                                                                                               0,
                                                                                                               0)
                                                                                                          ,
                                                                                                          /* 1 */
                                                                                                          new VdbeOpList
                                                                                                              (OPCode.OP_String8,
                                                                                                               0,
                                                                                                               3,
                                                                                                               0)
                                                                                                          ,
                                                                                                          /* 2 */
                                                                                                          new VdbeOpList
                                                                                                              (OPCode.OP_ResultRow,
                                                                                                               3,
                                                                                                               1,
                                                                                                               0)
                                                                                                          ,
                                                                                                      };

                                                                                            bool isQuick
                                                                                                =
                                                                                                (zLeft[0
                                                                                                     ] ==
                                                                                                 'q');

                                                                                            /* Initialize the VDBE program */
                                                                                            if (
                                                                                                Prepare.ReadSchema
                                                                                                    (pParse) !=
                                                                                                0)
                                                                                                goto
                                                                                                    pragma_out;
                                                                                            pParse.nMem
                                                                                                = 6;
                                                                                            VdbeAux.VdbeSetNumCols
                                                                                                (v, 1);
                                                                                            VdbeAux.VdbeSetColName
                                                                                                (v, 0,
                                                                                                 VdbeColnameType.COLNAME_NAME,
                                                                                                 "integrity_check",
                                                                                                 Const.SQLITE_STATIC);

                                                                                            /* Set the maximum error count */
                                                                                            mxErr =
                                                                                                SQLITE_INTEGRITY_CHECK_ERROR_MAX;
                                                                                            if (
                                                                                                zRight !=
                                                                                                null)
                                                                                            {
                                                                                                mxErr =
                                                                                                    Custom.Atoi
                                                                                                        (zRight);
                                                                                                if (
                                                                                                    mxErr <=
                                                                                                    0)
                                                                                                {
                                                                                                    mxErr
                                                                                                        =
                                                                                                        SQLITE_INTEGRITY_CHECK_ERROR_MAX;
                                                                                                }
                                                                                            }
                                                                                            VdbeAux.VdbeAddOp2
                                                                                                (v,
                                                                                                 OPCode.OP_Integer,
                                                                                                 mxErr,
                                                                                                 1);
                                                                                                /* reg[1] holds errors left */

                                                                                            /* Do an integrity check on each database file */
                                                                                            for (i = 0;
                                                                                                 i <
                                                                                                 db.nDb;
                                                                                                 i++)
                                                                                            {
                                                                                                HashElem
                                                                                                    x;
                                                                                                Hash
                                                                                                    pTbls;
                                                                                                int cnt
                                                                                                    = 0;

                                                                                                if (
                                                                                                    Const.OMIT_TEMPDB !=
                                                                                                    0 &&
                                                                                                    i ==
                                                                                                    1)
                                                                                                    continue;

                                                                                                Build.CodeVerifySchema
                                                                                                    (pParse,
                                                                                                     i);
                                                                                                addr =
                                                                                                    VdbeAux.VdbeAddOp1
                                                                                                        (v,
                                                                                                         OPCode.OP_IfPos,
                                                                                                         1);
                                                                                                    /* Halt if out of errors */
                                                                                                VdbeAux.VdbeAddOp2
                                                                                                    (v,
                                                                                                     OPCode.OP_Halt,
                                                                                                     0,
                                                                                                     0);
                                                                                                VdbeAux.VdbeJumpHere
                                                                                                    (v,
                                                                                                     addr);

                                                                                                /* Do an integrity check of the B-Tree
                                                        **
                                                        ** Begin by filling registers 2, 3, ... with the root pages numbers
                                                        ** for all tables and indices in the database.
                                                        */
                                                                                                pTbls =
                                                                                                    db.
                                                                                                        aDb
                                                                                                        [
                                                                                                            i
                                                                                                        ]
                                                                                                        .
                                                                                                        pSchema
                                                                                                        .
                                                                                                        tblHash;
                                                                                                for (
                                                                                                    x =
                                                                                                    pTbls
                                                                                                        .
                                                                                                        first;
                                                                                                    x !=
                                                                                                    null;
                                                                                                    x =
                                                                                                    x.
                                                                                                        next)
                                                                                                {
//          for(x=HashHelper.HashFirst(pTbls); x; x=HashHelper.HashNext(x)){
                                                                                                    var
                                                                                                        pTab
                                                                                                            =
                                                                                                            (
                                                                                                            Table
                                                                                                            )
                                                                                                            x
                                                                                                                .
                                                                                                                data;
                                                                                                        // HashHelper.HashData( x );
                                                                                                    Index
                                                                                                        pIdx;
                                                                                                    VdbeAux.VdbeAddOp2
                                                                                                        (v,
                                                                                                         OPCode.OP_Integer,
                                                                                                         pTab
                                                                                                             .
                                                                                                             tnum,
                                                                                                         2 +
                                                                                                         cnt);
                                                                                                    cnt
                                                                                                        ++;
                                                                                                    for
                                                                                                        (
                                                                                                        pIdx
                                                                                                        =
                                                                                                        pTab
                                                                                                            .
                                                                                                            pIndex;
                                                                                                        pIdx !=
                                                                                                        null;
                                                                                                        pIdx
                                                                                                        =
                                                                                                        pIdx
                                                                                                            .
                                                                                                            pNext)
                                                                                                    {
                                                                                                        VdbeAux.VdbeAddOp2
                                                                                                            (v,
                                                                                                             OPCode.OP_Integer,
                                                                                                             pIdx
                                                                                                                 .
                                                                                                                 tnum,
                                                                                                             2 +
                                                                                                             cnt);
                                                                                                        cnt
                                                                                                            ++;
                                                                                                    }
                                                                                                }

                                                                                                /* Make sure sufficient number of registers have been allocated */
                                                                                                if (
                                                                                                    pParse
                                                                                                        .
                                                                                                        nMem <
                                                                                                    cnt +
                                                                                                    4)
                                                                                                {
                                                                                                    pParse
                                                                                                        .
                                                                                                        nMem
                                                                                                        =
                                                                                                        cnt +
                                                                                                        4;
                                                                                                }

                                                                                                /* Do the b-tree integrity checks */
                                                                                                VdbeAux.VdbeAddOp3
                                                                                                    (v,
                                                                                                     OPCode.OP_IntegrityCk,
                                                                                                     2,
                                                                                                     cnt,
                                                                                                     1);
                                                                                                VdbeAux.VdbeChangeP5
                                                                                                    (v,
                                                                                                     (
                                                                                                     byte
                                                                                                     ) i);
                                                                                                addr =
                                                                                                    VdbeAux.VdbeAddOp1
                                                                                                        (v,
                                                                                                         OPCode.OP_IsNull,
                                                                                                         2);
                                                                                                VdbeAux.VdbeAddOp4
                                                                                                    (v,
                                                                                                     OPCode.OP_String8,
                                                                                                     0,
                                                                                                     3,
                                                                                                     0,
                                                                                                     Print.MPrintf
                                                                                                         (db,
                                                                                                          "*** in database %s ***\n",
                                                                                                          db
                                                                                                              .
                                                                                                              aDb
                                                                                                              [
                                                                                                                  i
                                                                                                              ]
                                                                                                              .
                                                                                                              zName),
                                                                                                     P4Type.P4_DYNAMIC);
                                                                                                VdbeAux.VdbeAddOp3
                                                                                                    (v,
                                                                                                     OPCode.OP_Move,
                                                                                                     2,
                                                                                                     4,
                                                                                                     1);
                                                                                                VdbeAux.VdbeAddOp3
                                                                                                    (v,
                                                                                                     OPCode.OP_Concat,
                                                                                                     4,
                                                                                                     3,
                                                                                                     2);
                                                                                                VdbeAux.VdbeAddOp2
                                                                                                    (v,
                                                                                                     OPCode.OP_ResultRow,
                                                                                                     2,
                                                                                                     1);
                                                                                                VdbeAux.VdbeJumpHere
                                                                                                    (v,
                                                                                                     addr);

                                                                                                /* Make sure all the indices are constructed correctly.
                                                        */
                                                                                                for (
                                                                                                    x =
                                                                                                    pTbls
                                                                                                        .
                                                                                                        first;
                                                                                                    x !=
                                                                                                    null &&
                                                                                                    !isQuick;
                                                                                                    x =
                                                                                                    x.
                                                                                                        next)
                                                                                                {
                                                                                                    ;
                                                                                                        //          for(x=HashHelper.HashFirst(pTbls); x && !isQuick; x=HashHelper.HashNext(x)){
                                                                                                    var
                                                                                                        pTab
                                                                                                            =
                                                                                                            (
                                                                                                            Table
                                                                                                            )
                                                                                                            x
                                                                                                                .
                                                                                                                data;
                                                                                                        // HashHelper.HashData( x );
                                                                                                    Index
                                                                                                        pIdx;
                                                                                                    int
                                                                                                        loopTop;

                                                                                                    if (
                                                                                                        pTab
                                                                                                            .
                                                                                                            pIndex ==
                                                                                                        null)
                                                                                                        continue;
                                                                                                    addr
                                                                                                        =
                                                                                                        VdbeAux.VdbeAddOp1
                                                                                                            (v,
                                                                                                             OPCode.OP_IfPos,
                                                                                                             1);
                                                                                                        /* Stop if out of errors */
                                                                                                    VdbeAux.VdbeAddOp2
                                                                                                        (v,
                                                                                                         OPCode.OP_Halt,
                                                                                                         0,
                                                                                                         0);
                                                                                                    VdbeAux.VdbeJumpHere
                                                                                                        (v,
                                                                                                         addr);
                                                                                                    sqlite3OpenTableAndIndices
                                                                                                        (pParse,
                                                                                                         pTab,
                                                                                                         1,
                                                                                                         OPCode.OP_OpenRead);
                                                                                                    VdbeAux.VdbeAddOp2
                                                                                                        (v,
                                                                                                         OPCode.OP_Integer,
                                                                                                         0,
                                                                                                         2);
                                                                                                        /* reg(2) will count entries */
                                                                                                    loopTop
                                                                                                        =
                                                                                                        VdbeAux.VdbeAddOp2
                                                                                                            (v,
                                                                                                             OPCode.OP_Rewind,
                                                                                                             1,
                                                                                                             0);
                                                                                                    VdbeAux.VdbeAddOp2
                                                                                                        (v,
                                                                                                         OPCode.OP_AddImm,
                                                                                                         2,
                                                                                                         1);
                                                                                                        /* increment entry count */
                                                                                                    for
                                                                                                        (
                                                                                                        j
                                                                                                        =
                                                                                                        0
                                                                                                        ,
                                                                                                        pIdx
                                                                                                        =
                                                                                                        pTab
                                                                                                            .
                                                                                                            pIndex;
                                                                                                        pIdx !=
                                                                                                        null;
                                                                                                        pIdx
                                                                                                        =
                                                                                                        pIdx
                                                                                                            .
                                                                                                            pNext
                                                                                                        ,
                                                                                                        j
                                                                                                            ++)
                                                                                                    {
                                                                                                        int
                                                                                                            jmp2;
                                                                                                        int
                                                                                                            r1;
                                                                                                        var
                                                                                                            idxErr
                                                                                                                = new[
                                                                                                                    ]
                                                                                                                      {
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_AddImm,
                                                                                                                               1,
                                                                                                                               -1,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_String8,
                                                                                                                               0,
                                                                                                                               3,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          /* 1 */
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_Rowid,
                                                                                                                               1,
                                                                                                                               4,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_String8,
                                                                                                                               0,
                                                                                                                               5,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          /* 3 */
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_String8,
                                                                                                                               0,
                                                                                                                               6,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          /* 4 */
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_Concat,
                                                                                                                               4,
                                                                                                                               3,
                                                                                                                               3)
                                                                                                                          ,
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_Concat,
                                                                                                                               5,
                                                                                                                               3,
                                                                                                                               3)
                                                                                                                          ,
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_Concat,
                                                                                                                               6,
                                                                                                                               3,
                                                                                                                               3)
                                                                                                                          ,
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_ResultRow,
                                                                                                                               3,
                                                                                                                               1,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_IfPos,
                                                                                                                               1,
                                                                                                                               0,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          /* 9 */
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_Halt,
                                                                                                                               0,
                                                                                                                               0,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                      };
                                                                                                        r1
                                                                                                            =
                                                                                                            sqlite3GenerateIndexKey
                                                                                                                (pParse,
                                                                                                                 pIdx,
                                                                                                                 1,
                                                                                                                 3,
                                                                                                                 false);
                                                                                                        jmp2
                                                                                                            =
                                                                                                            VdbeAux.VdbeAddOp4Int
                                                                                                                (v,
                                                                                                                 OPCode.OP_Found,
                                                                                                                 j +
                                                                                                                 2,
                                                                                                                 0,
                                                                                                                 r1,
                                                                                                                 pIdx
                                                                                                                     .
                                                                                                                     nColumn +
                                                                                                                 1);
                                                                                                        addr
                                                                                                            =
                                                                                                            VdbeAux.VdbeAddOpList
                                                                                                                (v,
                                                                                                                 Utility.ArraySize
                                                                                                                     (idxErr),
                                                                                                                 idxErr);
                                                                                                        VdbeAux.VdbeChangeP4
                                                                                                            (v,
                                                                                                             addr +
                                                                                                             1,
                                                                                                             "rowid ",
                                                                                                             Const.SQLITE_STATIC);
                                                                                                        VdbeAux.VdbeChangeP4
                                                                                                            (v,
                                                                                                             addr +
                                                                                                             3,
                                                                                                             " missing from index ",
                                                                                                             Const.SQLITE_STATIC);
                                                                                                        VdbeAux.VdbeChangeP4
                                                                                                            (v,
                                                                                                             addr +
                                                                                                             4,
                                                                                                             pIdx
                                                                                                                 .
                                                                                                                 zName,
                                                                                                             P4Type.P4_STATIC);
                                                                                                        VdbeAux.VdbeJumpHere
                                                                                                            (v,
                                                                                                             addr +
                                                                                                             9);
                                                                                                        VdbeAux.VdbeJumpHere
                                                                                                            (v,
                                                                                                             jmp2);
                                                                                                    }
                                                                                                    VdbeAux.VdbeAddOp2
                                                                                                        (v,
                                                                                                         OPCode.OP_Next,
                                                                                                         1,
                                                                                                         loopTop +
                                                                                                         1);
                                                                                                    VdbeAux.VdbeJumpHere
                                                                                                        (v,
                                                                                                         loopTop);
                                                                                                    for
                                                                                                        (
                                                                                                        j
                                                                                                        =
                                                                                                        0
                                                                                                        ,
                                                                                                        pIdx
                                                                                                        =
                                                                                                        pTab
                                                                                                            .
                                                                                                            pIndex;
                                                                                                        pIdx !=
                                                                                                        null;
                                                                                                        pIdx
                                                                                                        =
                                                                                                        pIdx
                                                                                                            .
                                                                                                            pNext
                                                                                                        ,
                                                                                                        j
                                                                                                            ++)
                                                                                                    {
                                                                                                        var
                                                                                                            cntIdx
                                                                                                                = new[
                                                                                                                    ]
                                                                                                                      {
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_Integer,
                                                                                                                               0,
                                                                                                                               3,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_Rewind,
                                                                                                                               0,
                                                                                                                               0,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          /* 1 */
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_AddImm,
                                                                                                                               3,
                                                                                                                               1,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_Next,
                                                                                                                               0,
                                                                                                                               0,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          /* 3 */
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_Eq,
                                                                                                                               2,
                                                                                                                               0,
                                                                                                                               3)
                                                                                                                          ,
                                                                                                                          /* 4 */
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_AddImm,
                                                                                                                               1,
                                                                                                                               -1,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_String8,
                                                                                                                               0,
                                                                                                                               2,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          /* 6 */
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_String8,
                                                                                                                               0,
                                                                                                                               3,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          /* 7 */
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_Concat,
                                                                                                                               3,
                                                                                                                               2,
                                                                                                                               2)
                                                                                                                          ,
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_ResultRow,
                                                                                                                               2,
                                                                                                                               1,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                      };
                                                                                                        addr
                                                                                                            =
                                                                                                            VdbeAux.VdbeAddOp1
                                                                                                                (v,
                                                                                                                 OPCode.OP_IfPos,
                                                                                                                 1);
                                                                                                        VdbeAux.VdbeAddOp2
                                                                                                            (v,
                                                                                                             OPCode.OP_Halt,
                                                                                                             0,
                                                                                                             0);
                                                                                                        VdbeAux.VdbeJumpHere
                                                                                                            (v,
                                                                                                             addr);
                                                                                                        addr
                                                                                                            =
                                                                                                            VdbeAux.VdbeAddOpList
                                                                                                                (v,
                                                                                                                 Utility.ArraySize
                                                                                                                     (cntIdx),
                                                                                                                 cntIdx);
                                                                                                        VdbeAux.VdbeChangeP1
                                                                                                            (v,
                                                                                                             addr +
                                                                                                             1,
                                                                                                             j +
                                                                                                             2);
                                                                                                        VdbeAux.VdbeChangeP2
                                                                                                            (v,
                                                                                                             addr +
                                                                                                             1,
                                                                                                             addr +
                                                                                                             4);
                                                                                                        VdbeAux.VdbeChangeP1
                                                                                                            (v,
                                                                                                             addr +
                                                                                                             3,
                                                                                                             j +
                                                                                                             2);
                                                                                                        VdbeAux.VdbeChangeP2
                                                                                                            (v,
                                                                                                             addr +
                                                                                                             3,
                                                                                                             addr +
                                                                                                             2);
                                                                                                        VdbeAux.VdbeJumpHere
                                                                                                            (v,
                                                                                                             addr +
                                                                                                             4);
                                                                                                        VdbeAux.VdbeChangeP4
                                                                                                            (v,
                                                                                                             addr +
                                                                                                             6,
                                                                                                             "wrong # of entries in index ",
                                                                                                             P4Type.P4_STATIC);
                                                                                                        VdbeAux.VdbeChangeP4
                                                                                                            (v,
                                                                                                             addr +
                                                                                                             7,
                                                                                                             pIdx
                                                                                                                 .
                                                                                                                 zName,
                                                                                                             P4Type.P4_STATIC);
                                                                                                    }
                                                                                                }
                                                                                            }
                                                                                            addr =
                                                                                                VdbeAux.VdbeAddOpList
                                                                                                    (v,
                                                                                                     Utility.ArraySize
                                                                                                         (endCode),
                                                                                                     endCode);
                                                                                            VdbeAux.VdbeChangeP2
                                                                                                (v, addr,
                                                                                                 -mxErr);
                                                                                            VdbeAux.VdbeJumpHere
                                                                                                (v,
                                                                                                 addr +
                                                                                                 1);
                                                                                            VdbeAux.VdbeChangeP4
                                                                                                (v,
                                                                                                 addr +
                                                                                                 2, "ok",
                                                                                                 P4Type.P4_STATIC);
                                                                                        }
                                                                                        else
#endif
                                                                                            // * SQLITE_OMIT_INTEGRITY_CHECK */

                                                                                            /*
**   PRAGMA encoding
**   PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be"
**
** In its first form, this pragma returns the encoding of the main
** database. If the database is not initialized, it is initialized now.
**
** The second form of this pragma is a no-op if the main database file
** has not already been initialized. In this case it sets the default
** encoding that will be used for the main database file if a new file
** is created. If an existing main database file is opened, then the
** default text encoding for the existing database is used.
**
** In all cases new databases created using the ATTACH command are
** created to use the same default text encoding as the main database. If
** the main database has not been initialized and/or created when ATTACH
** is executed, this is done before the ATTACH operation.
**
** In the second form this pragma sets the text encoding to be used in
** new database files created using this database handle. It is only
** useful if invoked immediately after the main database i
*/ if (
                                                                                                Utility.Sqlite3StrICmp
                                                                                                    (zLeft,
                                                                                                     "encoding") ==
                                                                                                0)
                                                                                            {
                                                                                                var
                                                                                                    encnames
                                                                                                        = new[
                                                                                                            ]
                                                                                                              {
                                                                                                                  new EncName
                                                                                                                      ("UTF8",
                                                                                                                       Const.SQLITE_UTF8)
                                                                                                                  ,
                                                                                                                  new EncName
                                                                                                                      ("UTF-8",
                                                                                                                       Const.SQLITE_UTF8)
                                                                                                                  ,
                                                                                                                  /* Must be element [1] */
                                                                                                                  new EncName
                                                                                                                      ("UTF-16le",
                                                                                                                       Const.SQLITE_UTF16LE)
                                                                                                                  ,
                                                                                                                  /* Must be element [2] */
                                                                                                                  new EncName
                                                                                                                      ("UTF-16be",
                                                                                                                       Const.SQLITE_UTF16BE)
                                                                                                                  ,
                                                                                                                  /* Must be element [3] */
                                                                                                                  new EncName
                                                                                                                      ("UTF16le",
                                                                                                                       Const.SQLITE_UTF16LE)
                                                                                                                  ,
                                                                                                                  new EncName
                                                                                                                      ("UTF16be",
                                                                                                                       Const.SQLITE_UTF16BE)
                                                                                                                  ,
                                                                                                                  new EncName
                                                                                                                      ("UTF-16",
                                                                                                                       0)
                                                                                                                  ,
                                                                                                                  /* SQLITE_UTF16NATIVE */
                                                                                                                  new EncName
                                                                                                                      ("UTF16",
                                                                                                                       0)
                                                                                                                  ,
                                                                                                                  /* SQLITE_UTF16NATIVE */
                                                                                                                  new EncName
                                                                                                                      (null,
                                                                                                                       0)
                                                                                                              };
                                                                                                int iEnc;
                                                                                                if (
                                                                                                    null ==
                                                                                                    zRight)
                                                                                                {
                                                                                                    /* "PRAGMA encoding" */
                                                                                                    if (
                                                                                                        Prepare.ReadSchema
                                                                                                            (pParse) !=
                                                                                                        0)
                                                                                                        goto
                                                                                                            pragma_out;
                                                                                                    VdbeAux.VdbeSetNumCols
                                                                                                        (v,
                                                                                                         1);
                                                                                                    VdbeAux.VdbeSetColName
                                                                                                        (v,
                                                                                                         0,
                                                                                                         VdbeColnameType.COLNAME_NAME,
                                                                                                         "encoding",
                                                                                                         Const.SQLITE_STATIC);
                                                                                                    VdbeAux.VdbeAddOp2
                                                                                                        (v,
                                                                                                         OPCode.OP_String8,
                                                                                                         0,
                                                                                                         1);
                                                                                                    Debug
                                                                                                        .
                                                                                                        Assert
                                                                                                        (encnames
                                                                                                             [
                                                                                                                 Const.SQLITE_UTF8
                                                                                                             ]
                                                                                                             .
                                                                                                             enc ==
                                                                                                         Const.SQLITE_UTF8);
                                                                                                    Debug
                                                                                                        .
                                                                                                        Assert
                                                                                                        (encnames
                                                                                                             [
                                                                                                                 Const.SQLITE_UTF16LE
                                                                                                             ]
                                                                                                             .
                                                                                                             enc ==
                                                                                                         Const.SQLITE_UTF16LE);
                                                                                                    Debug
                                                                                                        .
                                                                                                        Assert
                                                                                                        (encnames
                                                                                                             [
                                                                                                                 Const.SQLITE_UTF16BE
                                                                                                             ]
                                                                                                             .
                                                                                                             enc ==
                                                                                                         Const.SQLITE_UTF16BE);
                                                                                                    VdbeAux.VdbeChangeP4
                                                                                                        (v,
                                                                                                         -1,
                                                                                                         encnames
                                                                                                             [
                                                                                                                 Helper.ENC
                                                                                                                     (pParse
                                                                                                                          .
                                                                                                                          db)
                                                                                                             ]
                                                                                                             .
                                                                                                             zName,
                                                                                                         P4Type.P4_STATIC);
                                                                                                    VdbeAux.VdbeAddOp2
                                                                                                        (v,
                                                                                                         OPCode.OP_ResultRow,
                                                                                                         1,
                                                                                                         1);
                                                                                                }
#if !SQLITE_OMIT_UTF16
else
{                        /* "PRAGMA encoding = XXX" */
/* Only change the value of sqlite.enc if the database handle is not
** initialized. If the main database exists, the new sqlite.enc value
** will be overwritten when the schema is next loaded. If it does not
** already exists, it will be created to use the new encoding value.
*/
if (
//!(Helper.DbHasProperty(db, 0, DBSchemaFlag.DB_SchemaLoaded)) ||
//Helper.DbHasProperty(db, 0, DBSchemaFlag.DB_Empty)
( db.flags & DBSchemaFlag.DB_SchemaLoaded ) != DBSchemaFlag.DB_SchemaLoaded || ( db.flags & DBSchemaFlag.DB_Empty ) == DBSchemaFlag.DB_Empty
)
{
for ( iEnc = 0 ; encnames[iEnc].zName != null ; iEnc++ )
{
if ( 0 == Utility.Sqlite3StrICmp( zRight, encnames[iEnc].zName ) )
{
pParse.db.aDbStatic[0].pSchema.enc = encnames[iEnc].enc != 0 ? encnames[iEnc].enc : SQLITE_UTF16NATIVE;
break;
}
}
if ( encnames[iEnc].zName == null )
{
Utility.Sqlite3ErrorMsg( pParse, "unsupported encoding: %s", zRight );
}
}
}
#endif
                                                                                            }
                                                                                            else

#if !SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
                                                                                                /*
**   PRAGMA [database.]schema_version
**   PRAGMA [database.]schema_version = <integer>
**
**   PRAGMA [database.]user_version
**   PRAGMA [database.]user_version = <integer>
**
** The pragma's schema_version and user_version are used to set or get
** the value of the schema-version and user-version, respectively. Both
** the schema-version and the user-version are 32-bit signed integers
** stored in the database header.
**
** The schema-cookie is usually only manipulated internally by SQLite. It
** is incremented by SQLite whenever the database schema is modified (by
** creating or dropping a table or index). The schema version is used by
** SQLite each time a query is executed to ensure that the internal cache
** of the schema used when compiling the SQL query matches the schema of
** the database against which the compiled query is actually executed.
** Subverting this mechanism by using "PRAGMA schema_version" to modify
** the schema-version is potentially dangerous and may lead to program
** crashes or database corruption. Use with caution!
**
** The user-version is not used internally by SQLite. It may be used by
** applications for any purpose.
*/ if (
                                                                                                    Utility.Sqlite3StrICmp
                                                                                                        (zLeft,
                                                                                                         "schema_version") ==
                                                                                                    0
                                                                                                    ||
                                                                                                    Utility.Sqlite3StrICmp
                                                                                                        (zLeft,
                                                                                                         "user_version") ==
                                                                                                    0
                                                                                                    ||
                                                                                                    Utility.Sqlite3StrICmp
                                                                                                        (zLeft,
                                                                                                         "freelist_count") ==
                                                                                                    0
                                                                                                    )
                                                                                                {
                                                                                                    int
                                                                                                        iCookie;
                                                                                                        /* Cookie index. 1 for schema-cookie, 6 for user-cookie. */
                                                                                                    VdbeAux.VdbeUsesBtree
                                                                                                        (v,
                                                                                                         iDb);
                                                                                                    switch
                                                                                                        (
                                                                                                        zLeft
                                                                                                            [
                                                                                                                0
                                                                                                            ]
                                                                                                        )
                                                                                                    {
                                                                                                        case
                                                                                                            'f'
                                                                                                            :
                                                                                                        case
                                                                                                            'F'
                                                                                                            :
                                                                                                            iCookie
                                                                                                                =
                                                                                                                BtreeMeta.BTREE_FREE_PAGE_COUNT;
                                                                                                            break;
                                                                                                        case
                                                                                                            's'
                                                                                                            :
                                                                                                        case
                                                                                                            'S'
                                                                                                            :
                                                                                                            iCookie
                                                                                                                =
                                                                                                                BtreeMeta.BTREE_SCHEMA_VERSION;
                                                                                                            break;
                                                                                                        default
                                                                                                            :
                                                                                                            iCookie
                                                                                                                =
                                                                                                                BtreeMeta.BTREE_USER_VERSION;
                                                                                                            break;
                                                                                                    }

                                                                                                    if (
                                                                                                        zRight !=
                                                                                                        null &&
                                                                                                        iCookie !=
                                                                                                        BtreeMeta.BTREE_FREE_PAGE_COUNT)
                                                                                                    {
                                                                                                        /* Write the specified cookie value */
                                                                                                        var
                                                                                                            setCookie
                                                                                                                = new[
                                                                                                                    ]
                                                                                                                      {
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_Transaction,
                                                                                                                               0,
                                                                                                                               1,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          /* 0 */
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_Integer,
                                                                                                                               0,
                                                                                                                               1,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          /* 1 */
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_SetCookie,
                                                                                                                               0,
                                                                                                                               0,
                                                                                                                               1)
                                                                                                                          ,
                                                                                                                          /* 2 */
                                                                                                                      };
                                                                                                        int
                                                                                                            addr
                                                                                                                =
                                                                                                                VdbeAux.VdbeAddOpList
                                                                                                                    (v,
                                                                                                                     Utility.ArraySize
                                                                                                                         (setCookie),
                                                                                                                     setCookie);
                                                                                                        VdbeAux.VdbeChangeP1
                                                                                                            (v,
                                                                                                             addr,
                                                                                                             iDb);
                                                                                                        VdbeAux.VdbeChangeP1
                                                                                                            (v,
                                                                                                             addr +
                                                                                                             1,
                                                                                                             Custom.Atoi
                                                                                                                 (zRight));
                                                                                                        VdbeAux.VdbeChangeP1
                                                                                                            (v,
                                                                                                             addr +
                                                                                                             2,
                                                                                                             iDb);
                                                                                                        VdbeAux.VdbeChangeP2
                                                                                                            (v,
                                                                                                             addr +
                                                                                                             2,
                                                                                                             iCookie);
                                                                                                    }
                                                                                                    else
                                                                                                    {
                                                                                                        /* Read the specified cookie value */
                                                                                                        var
                                                                                                            readCookie
                                                                                                                = new[
                                                                                                                    ]
                                                                                                                      {
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_Transaction,
                                                                                                                               0,
                                                                                                                               0,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          /* 0 */
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_ReadCookie,
                                                                                                                               0,
                                                                                                                               1,
                                                                                                                               0)
                                                                                                                          ,
                                                                                                                          /* 1 */
                                                                                                                          new VdbeOpList
                                                                                                                              (OPCode.OP_ResultRow,
                                                                                                                               1,
                                                                                                                               1,
                                                                                                                               0)
                                                                                                                      };
                                                                                                        int
                                                                                                            addr
                                                                                                                =
                                                                                                                VdbeAux.VdbeAddOpList
                                                                                                                    (v,
                                                                                                                     readCookie
                                                                                                                         .
                                                                                                                         Length,
                                                                                                                     readCookie);
                                                                                                            // Utility.ArraySize(readCookie), readCookie);
                                                                                                        VdbeAux.VdbeChangeP1
                                                                                                            (v,
                                                                                                             addr,
                                                                                                             iDb);
                                                                                                        VdbeAux.VdbeChangeP1
                                                                                                            (v,
                                                                                                             addr +
                                                                                                             1,
                                                                                                             iDb);
                                                                                                        VdbeAux.VdbeChangeP3
                                                                                                            (v,
                                                                                                             addr +
                                                                                                             1,
                                                                                                             iCookie);
                                                                                                        VdbeAux.VdbeSetNumCols
                                                                                                            (v,
                                                                                                             1);
                                                                                                        VdbeAux.VdbeSetColName
                                                                                                            (v,
                                                                                                             0,
                                                                                                             VdbeColnameType.COLNAME_NAME,
                                                                                                             zLeft,
                                                                                                             Const.SQLITE_TRANSIENT);
                                                                                                    }
                                                                                                }
                                                                                                else if (
                                                                                                    Utility.Sqlite3StrICmp
                                                                                                        (zLeft,
                                                                                                         "reload_schema") ==
                                                                                                    0)
                                                                                                {
                                                                                                    /* force schema reloading*/
                                                                                                    Build.ResetInternalSchema
                                                                                                        (db,
                                                                                                         0);
                                                                                                }
                                                                                                else if
                                                                                                    (
                                                                                                    Utility.Sqlite3StrICmp
                                                                                                        (zLeft,
                                                                                                         "file_format") ==
                                                                                                    0)
                                                                                                {
                                                                                                    pDb
                                                                                                        .
                                                                                                        pSchema
                                                                                                        .
                                                                                                        file_format
                                                                                                        =
                                                                                                        (
                                                                                                        byte
                                                                                                        )
                                                                                                        Custom.Atoi
                                                                                                            (zRight);
                                                                                                    Build.ResetInternalSchema
                                                                                                        (db,
                                                                                                         0);
                                                                                                }

                                                                                                else
#endif
                                                                                                    // * SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */

#if !SQLITE_OMIT_COMPILEOPTION_DIAGS
                                                                                                    /*
  **   PRAGMA compile_options
  **
  ** Return the names of all compile-time options used in this build,
  ** one option per row.
  */ if
                                                                                                        (
                                                                                                        Utility.Sqlite3StrICmp
                                                                                                            (zLeft,
                                                                                                             "compile_options") ==
                                                                                                        0)
                                                                                                    {
                                                                                                        int
                                                                                                            i
                                                                                                                =
                                                                                                                0;
                                                                                                        string
                                                                                                            zOpt;
                                                                                                        VdbeAux.VdbeSetNumCols
                                                                                                            (v,
                                                                                                             1);
                                                                                                        pParse
                                                                                                            .
                                                                                                            nMem
                                                                                                            =
                                                                                                            1;
                                                                                                        VdbeAux.VdbeSetColName
                                                                                                            (v,
                                                                                                             0,
                                                                                                             VdbeColnameType.COLNAME_NAME,
                                                                                                             "compile_option",
                                                                                                             Const.SQLITE_STATIC);
                                                                                                        while
                                                                                                            (
                                                                                                            (zOpt
                                                                                                             =
                                                                                                             sqlite3_compileoption_get
                                                                                                                 (i
                                                                                                                      ++)) !=
                                                                                                            null)
                                                                                                        {
                                                                                                            VdbeAux.VdbeAddOp4
                                                                                                                (v,
                                                                                                                 OPCode.OP_String8,
                                                                                                                 0,
                                                                                                                 1,
                                                                                                                 0,
                                                                                                                 zOpt,
                                                                                                                 0);
                                                                                                            VdbeAux.VdbeAddOp2
                                                                                                                (v,
                                                                                                                 OPCode.OP_ResultRow,
                                                                                                                 1,
                                                                                                                 1);
                                                                                                        }
                                                                                                    }
                                                                                                    else
#endif
                                                                                                        //* SQLITE_OMIT_COMPILEOPTION_DIAGS */

#if SQLITE_DEBUG || SQLITE_TEST
                                                                                                        /*
** Report the current state of file logs for all databases
*/ if
                                                                                                            (
                                                                                                            Utility.Sqlite3StrICmp
                                                                                                                (zLeft,
                                                                                                                 "lock_status") ==
                                                                                                            0)
                                                                                                        {
                                                                                                            string
                                                                                                                [
                                                                                                                    ]
                                                                                                                azLockName
                                                                                                                    =
                                                                                                                    {
                                                                                                                        "unlocked"
                                                                                                                        ,
                                                                                                                        "shared"
                                                                                                                        ,
                                                                                                                        "reserved"
                                                                                                                        ,
                                                                                                                        "pending"
                                                                                                                        ,
                                                                                                                        "exclusive"
                                                                                                                    };
                                                                                                            int
                                                                                                                i;
                                                                                                            VdbeAux.VdbeSetNumCols
                                                                                                                (v,
                                                                                                                 2);
                                                                                                            pParse
                                                                                                                .
                                                                                                                nMem
                                                                                                                =
                                                                                                                2;
                                                                                                            VdbeAux.VdbeSetColName
                                                                                                                (v,
                                                                                                                 0,
                                                                                                                 VdbeColnameType.COLNAME_NAME,
                                                                                                                 "database",
                                                                                                                 Const.SQLITE_STATIC);
                                                                                                            VdbeAux.VdbeSetColName
                                                                                                                (v,
                                                                                                                 1,
                                                                                                                 VdbeColnameType.COLNAME_NAME,
                                                                                                                 "status",
                                                                                                                 Const.SQLITE_STATIC);
                                                                                                            for
                                                                                                                (
                                                                                                                i
                                                                                                                =
                                                                                                                0;
                                                                                                                i <
                                                                                                                db
                                                                                                                    .
                                                                                                                    nDb;
                                                                                                                i
                                                                                                                    ++)
                                                                                                            {
                                                                                                                Btree
                                                                                                                    pBt;
                                                                                                                Pager
                                                                                                                    pPager;
                                                                                                                string
                                                                                                                    zState
                                                                                                                        =
                                                                                                                        "unknown";
                                                                                                                int
                                                                                                                    j
                                                                                                                        =
                                                                                                                        0;
                                                                                                                if
                                                                                                                    (
                                                                                                                    db
                                                                                                                        .
                                                                                                                        aDb
                                                                                                                        [
                                                                                                                            i
                                                                                                                        ]
                                                                                                                        .
                                                                                                                        zName ==
                                                                                                                    null)
                                                                                                                    continue;
                                                                                                                VdbeAux.VdbeAddOp4
                                                                                                                    (v,
                                                                                                                     OPCode.OP_String8,
                                                                                                                     0,
                                                                                                                     1,
                                                                                                                     0,
                                                                                                                     db
                                                                                                                         .
                                                                                                                         aDb
                                                                                                                         [
                                                                                                                             i
                                                                                                                         ]
                                                                                                                         .
                                                                                                                         zName,
                                                                                                                     P4Type.P4_STATIC);
                                                                                                                pBt
                                                                                                                    =
                                                                                                                    db
                                                                                                                        .
                                                                                                                        aDb
                                                                                                                        [
                                                                                                                            i
                                                                                                                        ]
                                                                                                                        .
                                                                                                                        pBt;
                                                                                                                if
                                                                                                                    (
                                                                                                                    pBt ==
                                                                                                                    null ||
                                                                                                                    (pPager
                                                                                                                     =
                                                                                                                     sqlite3BtreePager
                                                                                                                         (pBt)) ==
                                                                                                                    null)
                                                                                                                {
                                                                                                                    zState
                                                                                                                        =
                                                                                                                        "closed";
                                                                                                                }
                                                                                                                else if
                                                                                                                    (sqlite3_file_control
                                                                                                                         (db,
                                                                                                                          i !=
                                                                                                                          0
                                                                                                                              ? db
                                                                                                                                    .
                                                                                                                                    aDb
                                                                                                                                    [
                                                                                                                                        i
                                                                                                                                    ]
                                                                                                                                    .
                                                                                                                                    zName
                                                                                                                              : null,
                                                                                                                          SQLITE_FCNTL_LOCKSTATE,
                                                                                                                          ref
                                                                                                                              j) ==
                                                                                                                     StatusCode.SQLITE_OK)
                                                                                                                {
                                                                                                                    zState
                                                                                                                        =
                                                                                                                        azLockName
                                                                                                                            [
                                                                                                                                j
                                                                                                                            ];
                                                                                                                }
                                                                                                                VdbeAux.VdbeAddOp4
                                                                                                                    (v,
                                                                                                                     OPCode.OP_String8,
                                                                                                                     0,
                                                                                                                     2,
                                                                                                                     0,
                                                                                                                     zState,
                                                                                                                     P4Type.P4_STATIC);
                                                                                                                VdbeAux.VdbeAddOp2
                                                                                                                    (v,
                                                                                                                     OPCode.OP_ResultRow,
                                                                                                                     1,
                                                                                                                     2);
                                                                                                            }
                                                                                                        }
                                                                                                        else
#endif

#if SQLITE_HAS_CODEC
if( Utility.Sqlite3StrICmp(zLeft, "key")==0 && zRight ){
sqlite3_key(db, zRight, Utility.Sqlite3Strlen30(zRight));
}else
if( Utility.Sqlite3StrICmp(zLeft, "rekey")==0 && zRight ){
sqlite3_rekey(db, zRight, Utility.Sqlite3Strlen30(zRight));
}else
if( zRight && (Utility.Sqlite3StrICmp(zLeft, "hexkey")==0 ||
Utility.Sqlite3StrICmp(zLeft, "hexrekey")==0) ){
int i, h1, h2;
char zKey[40];
for(i=0; (h1 = zRight[i])!=0 && (h2 = zRight[i+1])!=0; i+=2){
h1 += 9*(1&(h1>>6));
h2 += 9*(1&(h2>>6));
zKey[i/2] = (h2 & 0x0f) | ((h1 & 0xf)<<4);
}
if( (zLeft[3] & 0xf)==0xb ){
sqlite3_key(db, zKey, i/2);
}else{
sqlite3_rekey(db, zKey, i/2);
}
}else
#endif
#if SQLITE_HAS_CODEC || SQLITE_ENABLE_CEROD
if( Utility.Sqlite3StrICmp(zLeft, "activate_extensions")==0 ){
#if SQLITE_HAS_CODEC
if( Utility.Sqlite3StrNICmp(zRight, "see-", 4)==0 ){
sqlite3_activate_see(&zRight[4]);
}
#endif
#if SQLITE_ENABLE_CEROD
if( Utility.Sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){
sqlite3_activate_cerod(&zRight[6]);
}
#endif
}else
#endif
                                                                                                        {
                                                                                                            /* Empty ELSE clause */
                                                                                                        }

            /*
      ** Reset the safety level, in case the fullfsync flag or synchronous
      ** setting changed.
      */
#if !SQLITE_OMIT_PAGER_PRAGMAS
            if (db.autoCommit != 0)
            {
                sqlite3BtreeSetSafetyLevel(pDb.pBt, pDb.safety_level,
                                           ((db.flags & Flag.SQLITE_FullFSync) != 0) ? 1 : 0);
            }
#endif
            pragma_out:
            MemPool.DbFree(db, ref zLeft);
            MemPool.DbFree(db, ref zRight);
            ;
        }

#endif
        // * SQLITE_OMIT_PRAGMA
    }
}